@azure-id/orc 2.1.0 → 2.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +374 -0
- package/README.md +49 -36
- package/bin/build-agents.js +7 -5
- package/bin/cli.js +1006 -235
- package/bin/fix.js +21 -18
- package/bin/graph-extract.js +314 -6
- package/bin/graph-gain.js +83 -2
- package/bin/graph-map.js +23 -1
- package/bin/graph-notes.js +1 -1
- package/bin/graph-query.js +1362 -37
- package/bin/graph-resolve.js +1 -1
- package/bin/graph-shard.js +29 -6
- package/bin/graph-signals.js +5 -3
- package/bin/graph.js +7 -3
- package/bin/habit.js +1 -1
- package/bin/pricing.json +8 -1
- package/bin/trace-write.js +40 -11
- package/bin/verify-contracts.js +169 -60
- package/bin/verify-package.js +3 -3
- package/bin/webui/api.js +8 -0
- package/bin/webui/fixtures/extra.js +9 -9
- package/bin/webui/fixtures/flow.js +1 -1
- package/bin/webui/fixtures/index.js +2 -2
- package/bin/webui/fixtures/knowledge.js +8 -1
- package/bin/webui/fixtures/pact.js +112 -111
- package/bin/webui/fixtures/stats.js +2 -2
- package/bin/webui/i18n/en/knowledge.json +2 -0
- package/bin/webui/i18n/id/knowledge.json +2 -0
- package/bin/webui/js/panels/knowledge.js +17 -0
- package/guides/code-graph-benefit.md +116 -0
- package/guides/configuration.md +150 -0
- package/guides/documents.md +262 -0
- package/guides/extra-models.md +448 -0
- package/guides/habits-and-gotchas.md +152 -0
- package/guides/knowledge-reads.md +190 -0
- package/guides/model-selection.md +186 -0
- package/guides/rules.md +305 -0
- package/guides/status-line.md +344 -0
- package/mock-run/a-normal-day.md +2 -2
- package/mock-run/extra-slots.md +177 -177
- package/mock-run/orc-cli.md +3 -2
- package/mock-run/orc-doc.md +452 -448
- package/mock-run/orc-fast.md +2 -2
- package/mock-run/orc-quick.md +146 -146
- package/mock-run/orc.md +4 -4
- package/package.json +2 -1
- package/templates/agents/MODEL-MAPPING.md +12 -12
- package/templates/agents/{orc-executor-haiku-4-5.md → orc-executor-haiku-5-high.md} +21 -8
- package/templates/agents/orc-executor-opus-4-7-high.md +17 -5
- package/templates/agents/orc-executor-opus-4-7-med.md +17 -5
- package/templates/agents/orc-executor-opus-4-8-high.md +17 -5
- package/templates/agents/orc-executor-opus-5-high.md +17 -5
- package/templates/agents/orc-executor-opus-5-low.md +17 -5
- package/templates/agents/orc-executor-opus-5-med.md +17 -5
- package/templates/agents/orc-executor-sonnet-4-6-high.md +17 -5
- package/templates/agents/orc-executor-sonnet-5-high.md +17 -5
- package/templates/agents/orc-executor-sonnet-5-low.md +17 -5
- package/templates/agents/orc-executor-sonnet-5-med.md +17 -5
- package/templates/agents/{orc-graph-noter-sonnet-4-6-med.md → orc-graph-noter-haiku-5-high.md} +4 -4
- package/templates/agents/orc-planner-mini-opus-5-med.md +3 -1
- package/templates/agents/orc-planner-mini-sonnet-5-high.md +3 -1
- package/templates/agents/orc-planner-opus-5-med.md +3 -1
- package/templates/agents/{orc-recon-sonnet-4-6-med.md → orc-recon-sonnet-5-med.md} +4 -4
- package/templates/agents/{orc-trace-writer-haiku-4-5.md → orc-trace-writer-haiku-5-high.md} +4 -3
- package/templates/commands/orc-doc.md +128 -128
- package/templates/commands/orc-export.md +51 -46
- package/templates/commands/orc-fast.md +10 -10
- package/templates/hooks/README.md +8 -3
- package/templates/hooks/orc-effort-guard.js +105 -27
- package/templates/hooks/orc-graph-hook.js +252 -4
- package/templates/hooks/orc-statusline.js +13 -6
- package/templates/hooks/orc-trace.js +1 -1
- package/templates/skills/_shared/README.md +2 -2
- package/templates/skills/_shared/code-graph.md +185 -251
- package/templates/skills/_shared/extra-dispatch.md +4 -4
- package/templates/skills/_shared/lane-contract.md +7 -3
- package/templates/skills/_shared/opus5-only.md +3 -3
- package/templates/skills/_shared/phases/execution.md +13 -11
- package/templates/skills/_shared/phases/planning.md +27 -9
- package/templates/skills/_shared/phases/preflight.md +3 -3
- package/templates/skills/_shared/phases/review.md +4 -3
- package/templates/skills/_shared/phases/ship.md +7 -10
- package/templates/skills/_shared/phases/summary.md +2 -3
- package/templates/skills/_shared/phases/trace-verbs.md +21 -16
- package/templates/skills/_shared/phases/trace.md +3 -3
- package/templates/skills/_shared/phases/wiki-consult.md +2 -2
- package/templates/skills/_shared/pr-templates.md +108 -106
- package/templates/skills/_shared/read-ladder.md +8 -2
- package/templates/skills/_shared/return-validation.md +10 -6
- package/templates/skills/_shared/review-slice.md +1 -1
- package/templates/skills/_shared/stack-plan.md +135 -135
- package/templates/skills/_shared/wait.md +14 -2
- package/templates/skills/context-combiner/SKILL.md +2 -2
- package/templates/skills/orc/SKILL.md +7 -7
- package/templates/skills/orc/config.md +2 -2
- package/templates/skills/orc/examples/full-run-mock.md +7 -7
- package/templates/skills/orc/references/effort-and-mode.md +222 -222
- package/templates/skills/orc/schemas/planning-output.md +3 -0
- package/templates/skills/orc-aftermath/SKILL.md +15 -15
- package/templates/skills/orc-analyze/SKILL.md +2 -2
- package/templates/skills/orc-analyze-mini/SKILL.md +2 -2
- package/templates/skills/orc-boundary/SKILL.md +15 -15
- package/templates/skills/orc-boundary/references/card.md +81 -78
- package/templates/skills/orc-boundary/references/gate.md +113 -113
- package/templates/skills/orc-brainstorm/SKILL.md +15 -15
- package/templates/skills/orc-budget/SKILL.md +15 -15
- package/templates/skills/orc-challenge/README.md +1 -1
- package/templates/skills/orc-challenge/SKILL.md +16 -16
- package/templates/skills/orc-challenge/examples/council-full-roster.md +1 -1
- package/templates/skills/orc-claude/SKILL.md +4 -4
- package/templates/skills/orc-claude/examples/claude-run-mock.md +1 -1
- package/templates/skills/orc-diy/SKILL.md +2 -2
- package/templates/skills/orc-diy/references/blocks/wiki.md +26 -26
- package/templates/skills/orc-diy/references/flow-schema.md +2 -2
- package/templates/skills/orc-doc/README.md +2 -2
- package/templates/skills/orc-doc/SKILL.md +501 -490
- package/templates/skills/orc-doc/examples/orc-doc-prd-run.md +12 -1
- package/templates/skills/orc-doc/references/chunking.md +6 -4
- package/templates/skills/orc-doc/references/gates.md +311 -311
- package/templates/skills/orc-doc/references/resume-protocol.md +229 -228
- package/templates/skills/orc-explain/SKILL.md +88 -88
- package/templates/skills/orc-export/SKILL.md +190 -187
- package/templates/skills/orc-fast/SKILL.md +17 -14
- package/templates/skills/orc-grill/SKILL.md +16 -16
- package/templates/skills/orc-grill/references/grill-doc.md +1 -1
- package/templates/skills/orc-handoff/SKILL.md +11 -11
- package/templates/skills/orc-learn/SKILL.md +13 -13
- package/templates/skills/orc-learn/examples/learn-run-mock.md +2 -2
- package/templates/skills/orc-mini/SKILL.md +12 -12
- package/templates/skills/orc-mini/examples/mini-run-mock.md +4 -5
- package/templates/skills/orc-pact/SKILL.md +15 -15
- package/templates/skills/orc-pact/references/gate.md +70 -70
- package/templates/skills/orc-pattern/SKILL.md +3 -3
- package/templates/skills/orc-poly/SKILL.md +4 -4
- package/templates/skills/orc-poly/examples/poly-run-mock.md +51 -51
- package/templates/skills/orc-pr-driver/SKILL.md +4 -3
- package/templates/skills/orc-pr-driver/references/orc-run-split.md +108 -99
- package/templates/skills/orc-pr-setup/SKILL.md +2 -2
- package/templates/skills/orc-quick/README.md +11 -12
- package/templates/skills/orc-quick/SKILL.md +29 -32
- package/templates/skills/orc-quick/references/context-doc.md +5 -5
- package/templates/skills/orc-quick/references/dispatch-gate.md +10 -10
- package/templates/skills/orc-quick/references/gh-mode.md +2 -1
- package/templates/skills/orc-quick/references/look.md +34 -12
- package/templates/skills/orc-retro/SKILL.md +2 -2
- package/templates/skills/orc-retro/examples/retro-mock.md +2 -2
- package/templates/skills/orc-route/SKILL.md +2 -2
- package/templates/skills/orc-test/SKILL.md +6 -3
- package/templates/skills/orc-verify/SKILL.md +2 -2
- package/templates/skills/orc-wait/SKILL.md +10 -2
- package/templates/skills/orc-wiki/SKILL.md +4 -4
- package/templates/skills/orc-wiki/references/pattern-prewarm.md +19 -19
- package/templates/agents/orc-executor-sonnet-4-6-med.md +0 -155
|
@@ -24,8 +24,8 @@ version of a reference you haven't loaded this run. Detect the stack from the re
|
|
|
24
24
|
|
|
25
25
|
Confirm you are **Opus 4.8 high**, or **Opus 5.5 / Fable 5 at medium+** (both clear
|
|
26
26
|
the guard from medium up; Opus 5.5 also unlocks the [90,100] executor band). Effort
|
|
27
|
-
is hard-blocked by
|
|
28
|
-
|
|
27
|
+
is hard-blocked by `orc-effort-guard.js` (a Skill call: the live effort; a typed `/orc`:
|
|
28
|
+
the status line's reading, never a guess); the model cannot be — the statusline warns. On a weaker tier **STOP immediately**
|
|
29
29
|
and tell the user to switch the main session and re-run — never intake below it
|
|
30
30
|
(subagents cannot exceed the main tier, so the Opus executors silently downgrade).
|
|
31
31
|
|
|
@@ -37,7 +37,7 @@ themselves are this lane's own and stay here.
|
|
|
37
37
|
|
|
38
38
|
1. **You NEVER implement. You coordinate.** All execution, review, and verify
|
|
39
39
|
work is done by spawned subagents with scored models — even the smallest
|
|
40
|
-
task gets a cheap subagent (Sonnet
|
|
40
|
+
task gets a cheap subagent (the lowest band, Sonnet 5 low), never you.
|
|
41
41
|
2. **Disk is truth; conversation is a cache.** On any resume or suspected
|
|
42
42
|
compaction: re-read `state-of-play.md` then the checkpoint BEFORE acting.
|
|
43
43
|
3. **All run artifacts go in `.claude/orc/run/{run-slug}/`** (config `run_dir`,
|
|
@@ -100,8 +100,8 @@ session on Opus or the Opus pins silently fall back (the original "wrong model"
|
|
|
100
100
|
|
|
101
101
|
## Lane contract (`../_shared/lane-contract.md` — read it ONLY when a call exits ≠ 0)
|
|
102
102
|
|
|
103
|
-
- **Calls:** `orc lane calls orc --json` names
|
|
104
|
-
**An exit code is an ANSWER where it says so, not a failure.**
|
|
103
|
+
- **Calls:** `orc lane calls orc --json` names shared calls and exit codes.
|
|
104
|
+
**An exit code is an ANSWER where it says so, not a failure.** Own calls are here; make no other.
|
|
105
105
|
- **Config:** `orc lane config orc --json`. Obey `effective`, print every line
|
|
106
106
|
in `announce[]` VERBATIM at preflight, and honour `stops[]` before wave 1.
|
|
107
107
|
Never merge `.claude/orc.config.yaml` yourself (`../_shared/config-precedence.md`).
|
|
@@ -120,7 +120,7 @@ in the SAME step; store `trace_path`.
|
|
|
120
120
|
**Under `ultra_mode` the lane segment is `ultra`, not `orc`** (`run-ultra-<slug>-…`)
|
|
121
121
|
— the filename IS the per-lane data, so an ultra run named `orc` is counted as a
|
|
122
122
|
plain `/orc` run forever, hiding the costliest lane in every usage report.
|
|
123
|
-
**Phase close = `orc trace write --packet -`** (exit ≠ 0 → `orc-trace-writer-haiku-
|
|
123
|
+
**Phase close = `orc trace write --packet -`** (exit ≠ 0 → `orc-trace-writer-haiku-5-high`).
|
|
124
124
|
The first packet is solo — it repairs a hook-bootstrap filename.
|
|
125
125
|
`DISPATCH`/`VERIFY` models are derived from the agent NAME and checked against
|
|
126
126
|
each return's `actual_model`/`actual_effort` — surface any ⛔ DOWNGRADE to the
|
|
@@ -179,7 +179,7 @@ them; they are never dispatched as subagents).
|
|
|
179
179
|
- Phase 5.5 → `../_shared/phases/security-checklist.md`; 6.5 → `subskills/orc-testgen/`
|
|
180
180
|
- Phase 8 → `subskills/orc-pr/SKILL.md` (template `subskills/orc-pr/pr.md`);
|
|
181
181
|
stack gate → `subskills/orc-pr/stack-gate.md` + `_shared/pr-templates.md`
|
|
182
|
-
- Code graph
|
|
182
|
+
- Code graph — the four touchpoints (`../_shared/code-graph.md` §0), every call with `--if-enabled --json --brief`: (1) consult at preflight — print `probes["graph-status"].line`; `orc graph status --heal` only when `heal_needed`; exit 3 (`off` or `semi`) → no other graph call · (2) orient at planning — `orc graph map --focus=<3–6 words> --budget 800` ONCE, then `orc graph impact` + `orc graph cochange` on the candidate files · (3) anchors — one `orc graph ctx --for-slice <declared files> --focus=<words> [--refs=<task.precedent>] --anchors` per writing dispatch (a request that names one symbol: `ctx <symbol> --anchors` gives the card and the anchors in one call); its `card` goes into the slice VERBATIM as `graph_anchors`, with its `read all: …` line and its code block — never shorten it; With `graph_anchors` in the slice, list at most ONE wiki page path (the one about the feature's intent), not 1–3. ( none for one named file with no outside change) · (4) affected tests — `orc graph changes --files=<actual files>` at review. `orc graph update --notes-pending` only when `update_step` is `lane`. No lane runs the gain meter. Print each `line`; copy each `trace` VERBATIM
|
|
183
183
|
- Schemas (you own; pass slices only): `schemas/intent-spec.md`,
|
|
184
184
|
`schemas/planning-output.md`, `schemas/checkpoint.md`
|
|
185
185
|
- Worked example (orient only — never execute from it) → `examples/full-run-mock.md`
|
|
@@ -43,8 +43,8 @@ EFFORT, which is why the old four Opus rows are two. **Every band from score 41
|
|
|
43
43
|
needs an Opus 5.5 MAIN session** or it silently falls back to the session model
|
|
44
44
|
(the tier-honesty rule reports the downgrade) — that is the cost of this table.
|
|
45
45
|
|
|
46
|
-
**
|
|
47
|
-
`orc-executor-sonnet-4-6-
|
|
46
|
+
**Six executors are named by NO band** — `orc-executor-haiku-5-high`,
|
|
47
|
+
`orc-executor-sonnet-4-6-high`,
|
|
48
48
|
`orc-executor-opus-4-7-med`, `orc-executor-opus-4-7-high`,
|
|
49
49
|
`orc-executor-opus-4-8-high` and `orc-executor-opus-5-high`. They still ship,
|
|
50
50
|
reachable through `rubric_bands_override`, `orc diy`'s `fixed_executor` and
|
|
@@ -22,17 +22,17 @@ O: [6 tasks with declared_files incl. tests + per-file grounding attestations +
|
|
|
22
22
|
O: Refined: medium, partially dependent. Recommend PARALLEL waves. Confirm? U: yes. Batch pause? U: every 2 waves.
|
|
23
23
|
O: Facet scoring (planner facets → formula → band; facet gate: breadth + fan recomputed, risk cites checked):
|
|
24
24
|
T1 3·new-surface·stateful·new-tests·fan0/3·low = 6+18+16+8+9 = 57 → sonnet-5-high (keystone — every later task imports its enum)
|
|
25
|
-
T2 3·imitate·branching·new-tests·fan1/0·low = 6+8+8+8+5 = 35 → sonnet-
|
|
26
|
-
T3 3·imitate·branching·update-existing·fan1/0·low = 6+8+8+4+5 = 31 → sonnet-
|
|
27
|
-
T4 2·imitate·branching·update-existing·fan1/0·low = 6+8+8+4+5 = 31 → sonnet-
|
|
28
|
-
T5 1·mechanical·none·update-existing·fan0/0·low = 2+0+0+4 = 6 → haiku-
|
|
29
|
-
T6 1·mechanical·none·none·fan0/0·low = 2+0+0+0 = 2 → haiku-
|
|
25
|
+
T2 3·imitate·branching·new-tests·fan1/0·low = 6+8+8+8+5 = 35 → sonnet-5-high
|
|
26
|
+
T3 3·imitate·branching·update-existing·fan1/0·low = 6+8+8+4+5 = 31 → sonnet-5-high
|
|
27
|
+
T4 2·imitate·branching·update-existing·fan1/0·low = 6+8+8+4+5 = 31 → sonnet-5-high
|
|
28
|
+
T5 1·mechanical·none·update-existing·fan0/0·low = 2+0+0+4 = 6 → haiku-5-high
|
|
29
|
+
T6 1·mechanical·none·none·fan0/0·low = 2+0+0+0 = 2 → haiku-5-high
|
|
30
30
|
Plan: 6 tasks, 3 waves W1{T1} W2{T2,T3,T4} W3{T5,T6}, all spawned. Anticipated escalations? U: none, go.
|
|
31
31
|
|
|
32
32
|
## Phase 3 — Execution (ALL spawned; orchestrator coordinates only)
|
|
33
33
|
O: [checkpoint + state-of-play written into run/merchant-notifications/ BEFORE dispatch]
|
|
34
34
|
▶ W1: spawn Agent-A(T1, sonnet-5-high) — milestones 40%→100% — return validated ✓ (evidence: `yarn jest models/` exit 0, tail quoted; unmet[] empty) — log: DECISION type enum.
|
|
35
|
-
▶ W2: spawn 3 agents (sonnet-
|
|
35
|
+
▶ W2: spawn 3 agents (sonnet-5-high each).
|
|
36
36
|
Agent-C needs_context (1/2): "needs T1's enum interface" → O adjudicates in-scope → re-slices → resumes. (User never bothered.)
|
|
37
37
|
Agent-C user escalation: "digest send time?" → U: 07:00 fixed → ANSWER broadcast to log.
|
|
38
38
|
Returns validated ✓ · collision audit clean.
|
|
@@ -46,7 +46,7 @@ O: [checkpoint + state-of-play written into run/merchant-notifications/ BEFORE d
|
|
|
46
46
|
|
|
47
47
|
U: [next day, FRESH session, pastes block]
|
|
48
48
|
O: [state-of-play → checkpoint → re-anchored] "Resuming: merchant notifications (in-app+digest+prefs). Still correct?" U: yes.
|
|
49
|
-
▶ W3: spawn T5+T6 (haiku-
|
|
49
|
+
▶ W3: spawn T5+T6 (haiku-5-high) → done. All 6 complete.
|
|
50
50
|
|
|
51
51
|
## Phase 5 — Review (spawned worker, Opus 5.5 medium)
|
|
52
52
|
O: Code pattern? U: none. Findings (P0–P3 ladder, each P0–P2 anchored file:line + verbatim quote):
|
|
@@ -1,222 +1,222 @@
|
|
|
1
|
-
# Reference — Effort, Dispatch Style, and Task Scoring
|
|
2
|
-
|
|
3
|
-
**Subagents ALWAYS do the work — the orchestrator never implements** (hard
|
|
4
|
-
rule 1). The orchestrator is Opus 4.8 high: it doing implementation is the most
|
|
5
|
-
costly way possible, and it burns the context that must survive the whole run.
|
|
6
|
-
Spawning keeps orchestrator context lean so runs last longer before any pause.
|
|
7
|
-
|
|
8
|
-
Two INDEPENDENT axes. Never conflate them:
|
|
9
|
-
- **Run-level effort** (low/medium/high) → picks the **dispatch style**
|
|
10
|
-
(sequential vs parallel), which controls only **intra-wave concurrency** —
|
|
11
|
-
never WHO does the work, and never WHETHER waves exist.
|
|
12
|
-
- **Per-task score** (0–100) → picks each **worker's model**. Always applies.
|
|
13
|
-
|
|
14
|
-
A medium run can contain a 30-score task and a 95-score task in the same wave.
|
|
15
|
-
|
|
16
|
-
## Waves always exist; dispatch style is intra-wave only
|
|
17
|
-
|
|
18
|
-
**Wave computation runs for every run with ≥2 tasks, sequential included**
|
|
19
|
-
(dependency layers + conflict graph + `max_wave_tasks` cap — see
|
|
20
|
-
`wave-grouping.md`). Dispatch style does NOT decide whether there are waves; it
|
|
21
|
-
decides how a wave's tasks fire:
|
|
22
|
-
|
|
23
|
-
- **sequential** → a wave's tasks dispatch one at a time, in order; the wave
|
|
24
|
-
closes when all its tasks close;
|
|
25
|
-
- **parallel** → a wave's non-conflicting tasks dispatch at once (up to
|
|
26
|
-
`max_wave_tasks`).
|
|
27
|
-
|
|
28
|
-
The **wave-boundary batch pause binds to wave numbers, identically in both
|
|
29
|
-
styles** — a sequential run is NOT "no waves / per-task pauses". Show the wave
|
|
30
|
-
plan (wave → tasks → pause marks) to the user BEFORE wave 1 in both styles.
|
|
31
|
-
|
|
32
|
-
## Run-level effort → dispatch style (recommend, user confirms)
|
|
33
|
-
|
|
34
|
-
- **Low**, or heavy shared data/code → **sequential**: one scored subagent at a
|
|
35
|
-
time, in dependency order (still grouped into waves). Even a single trivial
|
|
36
|
-
task = one cheap subagent (typically Sonnet
|
|
37
|
-
orchestrator itself.
|
|
38
|
-
- **Medium** → sequential by default; **parallel** intra-wave if 3+ genuinely
|
|
39
|
-
independent areas.
|
|
40
|
-
- **High** with independent areas → **parallel** waves; consider worktrees for
|
|
41
|
-
isolation (merge at end).
|
|
42
|
-
|
|
43
|
-
Always RECOMMEND with a one-line why, and let the user pick. Tell them the
|
|
44
|
-
agent/task/wave counts, each task's scored model, and where batch pauses fall
|
|
45
|
-
BEFORE dispatching.
|
|
46
|
-
|
|
47
|
-
## Per-task scoring — facet-scored, arithmetic, two-writer
|
|
48
|
-
|
|
49
|
-
The score is **not judged** from a task title. The **planner** — the one party
|
|
50
|
-
that globbed and read every declared file — emits per-task `facets` (facts). The
|
|
51
|
-
**orchestrator** — who never read the code — computes the number arithmetically
|
|
52
|
-
and audits the facts. No vibes anywhere. Every task is scored, including tiny ones.
|
|
53
|
-
|
|
54
|
-
**1. Planner-emitted facets** (`planning-output.md` `facets` block, filled during
|
|
55
|
-
grounding — zero extra passes):
|
|
56
|
-
|
|
57
|
-
| Facet | Values |
|
|
58
|
-
|---|---|
|
|
59
|
-
| `breadth` | `len(declared_files)` — computed, not judged |
|
|
60
|
-
| `novelty` | mechanical · imitate · new-surface · novel-algorithm |
|
|
61
|
-
| `logic` | none · branching · stateful · algorithmic |
|
|
62
|
-
| `test_surface` | none · update-existing · new-tests |
|
|
63
|
-
| `risk` | `[]` or `[{class, cite}]` — class ∈ auth·money·migration·security·concurrency·data-integrity; **each entry MUST cite the file/requirement** |
|
|
64
|
-
| `uncertainty` | low · medium · high (+ one-line reason if not low) |
|
|
65
|
-
|
|
66
|
-
`fan_in`/`fan_out` are NOT emitted — the orchestrator computes them from
|
|
67
|
-
`depends_on` (forward = fan_in, reverse = fan_out).
|
|
68
|
-
|
|
69
|
-
**2. Orchestrator validation gate (Phase 2, deterministic — same bounce
|
|
70
|
-
mechanics as grounding):** emit `GATE facet pass|bounce`. Three checks:
|
|
71
|
-
|
|
72
|
-
- **Recompute** `breadth` (= `len(declared_files)`) and `fan_in`/`fan_out` from
|
|
73
|
-
the plan itself — a mismatch bounces.
|
|
74
|
-
- **MEMBERSHIP (v0.34.4):** `novelty`, `logic`, `test_surface` and `uncertainty`
|
|
75
|
-
must each be a member of their CLOSED set above, and every `risk[].class` must
|
|
76
|
-
be one of the six risk classes. A set lookup, as deterministic as the grounding
|
|
77
|
-
Glob. This is the check that was missing: the gate validated only the two
|
|
78
|
-
facets it could recompute and TRUSTED the four it could not, so a planner that
|
|
79
|
-
invented a `low|medium|high` scale produced an **arithmetically unscorable**
|
|
80
|
-
plan that passed the stated gate. There is no `N("low")` — and an orchestrator
|
|
81
|
-
applying `risk != [] -> floor 70` to prose risk strings floors EVERY task, a
|
|
82
|
-
two-band overshoot caused by a field's shape rather than by the work.
|
|
83
|
-
- **Cite check:** a `risk` entry with no `cite` bounces (unchanged).
|
|
84
|
-
|
|
85
|
-
A facet-vocabulary miss is a **FIELD-SHAPE bounce**: hand back the miss list and
|
|
86
|
-
say *do not re-plan* — the planner corrects only the offending `facets` blocks.
|
|
87
|
-
(It may also legitimately DROP a risk entry on the correction pass: implementation
|
|
88
|
-
hazards like test seeding or dependency discipline are not risk CLASSES. That
|
|
89
|
-
judgment is the planner's to make and is worth accepting.) Without this clause a
|
|
90
|
-
shape bounce risks costing a correct plan. A plan with no `facets` at all
|
|
91
|
-
(pre-v0.31.0) resumes on the legacy path — never bounced for the missing block.
|
|
92
|
-
|
|
93
|
-
**3. The fixed formula (the ONLY scoring text — this replaces base+adjusters):**
|
|
94
|
-
|
|
95
|
-
```
|
|
96
|
-
score = B(breadth) + N(novelty) + L(logic) + T(test_surface)
|
|
97
|
-
+ 5*min(fan_in,3) + 3*min(fan_out,3) + U(uncertainty)
|
|
98
|
-
|
|
99
|
-
B: 1f=2 2-3f=6 4-5f=10 6+f=15
|
|
100
|
-
N: mechanical=0 imitate=8 new-surface=18 novel-algorithm=30
|
|
101
|
-
L: none=0 branching=8 stateful=16 algorithmic=24
|
|
102
|
-
T: none=0 update-existing=4 new-tests=8
|
|
103
|
-
U: low=0 medium=6 high=12
|
|
104
|
-
|
|
105
|
-
risk ≠ [] → floor 70 (DERIVED from a cited risk facet, never remembered).
|
|
106
|
-
clamp 0..100 → the RESOLVED table (below).
|
|
107
|
-
```
|
|
108
|
-
|
|
109
|
-
**Which table (highest wins):** `opus5_only: true` (the 2-band Opus-5-only
|
|
110
|
-
preset: `[0,90)` low · `[90,100]` medium) → `rubric_bands_override`
|
|
111
|
-
(hand-written rows) → the default 5-band table. All three are in `config.md`.
|
|
112
|
-
The formula, the facets and the risk floor are IDENTICAL in every case — only
|
|
113
|
-
the score→agent mapping changes. Three consequences worth stating so nobody
|
|
114
|
-
re-derives them per run:
|
|
115
|
-
|
|
116
|
-
- **The risk floor still applies** — it raises the SCORE, then the resolved table
|
|
117
|
-
maps it. A floored task (≥70) lands `opus-5-low` in the default table and
|
|
118
|
-
`opus-5-low` under the Opus-5-only preset too: since v1.0.0 both tables answer
|
|
119
|
-
the floor with the same agent, and only a score of 90+ moves it to `opus-5-med`.
|
|
120
|
-
- **`opus5_only` FORCES** — while on, a hand-written `rubric_bands_override` is
|
|
121
|
-
ignored. It is the one selector that can shadow another; that is deliberate.
|
|
122
|
-
|
|
123
|
-
Show the user the full table (task, the facet vector, the arithmetic
|
|
124
|
-
`B+N+L+T+fan+U = raw`, any risk floor, final, override+reason if any, dispatched
|
|
125
|
-
model) BEFORE dispatching — an un-shown number is not a scored number. **Head it
|
|
126
|
-
with the RESOLVED table's name** (`5-band default` / `Opus-5-only ladder
|
|
127
|
-
(opus5_only)` / `custom (rubric_bands_override)`): the same logic
|
|
128
|
-
applies to the mapping as to the number.
|
|
129
|
-
|
|
130
|
-
**Extra (v0.50.0, `extra_enabled`) adds a `via` column and can make the head a
|
|
131
|
-
PAIR.** An Extra route row is an OVERLAY that outranks the tables above **only
|
|
132
|
-
for the scores it covers**, so a run can genuinely be running two tables at once
|
|
133
|
-
and the head names both (`5-band default + extra rows [0,30) [30,70)`). The
|
|
134
|
-
column reads `claude` or `extra:<profile> (<engine>)` and comes from
|
|
135
|
-
`orc extra resolve --json` — the formula, the facets and the risk floor are
|
|
136
|
-
untouched, and **the score is computed before the routing, never after it**. Two
|
|
137
|
-
consequences the table has to show rather than imply: a cited `risk[]` HOLDS THE
|
|
138
|
-
TASK BACK to its Claude band whatever the row says (`extra_risk_tasks: off`), and
|
|
139
|
-
the `model` for a foreign task is the FOREIGN model id, not a Claude tier.
|
|
140
|
-
Canonical: `../../_shared/extra-dispatch.md`.
|
|
141
|
-
|
|
142
|
-
**4. Consistency check:** two tasks whose facet vectors differ in **≤1 facet must
|
|
143
|
-
land in the same band** — or the SCORE line for the outlier **cites the one
|
|
144
|
-
differing facet**. This is the specific fix for sibling tasks in the same domain
|
|
145
|
-
drifting into three different bands.
|
|
146
|
-
|
|
147
|
-
**5. Override protocol** (unchanged): you may override the computed score. Record
|
|
148
|
-
`{computed_score, override_score, reason}` in the dispatch log. An override
|
|
149
|
-
without a reason is invalid.
|
|
150
|
-
|
|
151
|
-
## EVERY dispatch is scored — the fix-cycle rule
|
|
152
|
-
|
|
153
|
-
Fix-cycle dispatches — review-fix, verify-fix, the Phase-7 P2-batch, and any
|
|
154
|
-
requeue — are scored through the **same formula**, with two floors that stop a
|
|
155
|
-
fix in a risk area from silently dropping to a cheap model:
|
|
156
|
-
|
|
157
|
-
- **Inherit the ORIGINAL task's `risk` facets** when the fix touches its files —
|
|
158
|
-
a fix in a risk-floor area keeps the ≥70 floor (a userID/context-key fix can
|
|
159
|
-
never dispatch below `opus-5-low` again);
|
|
160
|
-
- a **P0/P1 fix never dispatches below the band of the task that produced the
|
|
161
|
-
finding.**
|
|
162
|
-
|
|
163
|
-
Emit a `SCORE task=fix-<n> …` line for each (they appear in the dispatch log and
|
|
164
|
-
the completion table like any task).
|
|
165
|
-
|
|
166
|
-
## Worked scoring examples (facet vectors — compare facet-by-facet, not by vibes)
|
|
167
|
-
|
|
168
|
-
Each row is the facet vector run through the formula. The number is arithmetic;
|
|
169
|
-
the band is what matters. Compare a new task to these facet-by-facet.
|
|
170
|
-
|
|
171
|
-
| Task | breadth·novelty·logic·test · fan_in/out · unc | Arithmetic | Band |
|
|
172
|
-
|---|---|---|---|
|
|
173
|
-
| Rename a config key across 4 files + its test | 5·mechanical·none·update-existing · 0/0 · low | 10+0+0+4 = **14** | sonnet-5-low [0,21) |
|
|
174
|
-
| New CRUD endpoint following a sibling route | 3·imitate·branching·new-tests · 1/0 · low | 6+8+8+8+5 = **35** | sonnet-5-high [31,41) |
|
|
175
|
-
| Bug fix across 2 files with a repro test | 3·imitate·branching·new-tests · 0/0 · medium | 6+8+8+8+6 = **36** | sonnet-5-high [31,41) |
|
|
176
|
-
| Isolated component from the design system | 3·new-surface·branching·new-tests · 0/0 · low | 6+18+8+8 = **40** | sonnet-5-high [31,41) |
|
|
177
|
-
| Notification model + enum other tasks consume | 3·new-surface·stateful·new-tests · 0/3 · low | 6+18+16+8+9 = **57** | opus-5-low [41,90) |
|
|
178
|
-
| Service-layer refactor behind a stable interface | 5·imitate·stateful·update-existing · 0/3 · medium | 10+8+16+4+9+6 = **53** | opus-5-low [41,90) |
|
|
179
|
-
| Add role check to payment-refund endpoint | 3·imitate·branching·new-tests · 0/0 · low · **risk=[auth,money]** | 30 raw → **floor 70** | opus-5-low [41,90) |
|
|
180
|
-
| Migrate orders table to split-name + backfill | 6·new-surface·stateful·new-tests · 1/3 · high · **risk=[migration,data-integrity]** | 15+18+16+8+5+9+12 = 83 (floor 70) → **83** | opus-5-low [41,90) |
|
|
181
|
-
|
|
182
|
-
Two disciplines the vectors encode: (1) a small diff is NOT a low score when a
|
|
183
|
-
cited `risk` facet forces the floor (the refund row — 30 raw, floored to 70); (2)
|
|
184
|
-
a big-looking task IS low when its facets are mechanical (the rename). The risk
|
|
185
|
-
floor is always DERIVED from a cited facet — the SCORE line names it, never
|
|
186
|
-
applies it silently.
|
|
187
|
-
|
|
188
|
-
## Model ladder → the single score→model table
|
|
189
|
-
|
|
190
|
-
The score→model mapping is NOT hardcoded here — it lives in `config.md` as ONE
|
|
191
|
-
canonical 5-band table (there is no longer a narrow/wide preset). Read config at
|
|
192
|
-
run start and map each task's final score through that table (or
|
|
193
|
-
`rubric_bands_override`). The orchestrator dispatches the executor agent BY NAME;
|
|
194
|
-
it does not request a raw model. `rubric_bands` sets only how many bands the
|
|
195
|
-
rubric REPORTS (score granularity), never which table is used.
|
|
196
|
-
|
|
197
|
-
The 5 bands (see config.md for the exact edges): `sonnet-5-low` [0,21) ·
|
|
198
|
-
`sonnet-5-med` [21,31) · `sonnet-5-high` [31,41) · `opus-5-low` [41,90) ·
|
|
199
|
-
`opus-5-med` [90,100]. Effort tiers rank
|
|
200
|
-
`low < medium < high < xhigh < max`.
|
|
201
|
-
|
|
202
|
-
## Fixed model assignments (not scored)
|
|
203
|
-
|
|
204
|
-
- **Orchestrator (you):** Opus 4.8 high — or Opus 5.5 / Fable 5 at medium+, the
|
|
205
|
-
two models that clear the guard from medium up. Never downgrade yourself.
|
|
206
|
-
- **Review** — Superpowers path: Sonnet 4.6, medium. OpenSpec/self path:
|
|
207
|
-
Opus 5.5, low (`orc-reviewer-opus-5-low`; medium until v2.1.0).
|
|
208
|
-
- **Verify:** Opus 5.5, medium (`orc-verifier-opus-5-med`).
|
|
209
|
-
- **Analyst:** Opus 5.5, high. **Planner:** Opus 5.5, medium. **Test author:**
|
|
210
|
-
Opus 5.5, medium. **Combiner:** Opus 5.5, high. **Ultra advisor/judge:** Opus 5.5,
|
|
211
|
-
xhigh — every core fixed role is pinned to Opus 5.5 as of v0.34.0.
|
|
212
|
-
- **Merge-conflict resolver:** Opus 4.8, medium.
|
|
213
|
-
|
|
214
|
-
Note: every band in the table above is a real dispatch target (sonnet-5 through
|
|
215
|
-
opus-5). If a model tier is unavailable in the environment, fall back UP to the
|
|
216
|
-
next capable tier (never silently substitute a different family/effort).
|
|
217
|
-
|
|
218
|
-
## Dispatch log (lives in the checkpoint)
|
|
219
|
-
|
|
220
|
-
Every spawn records: `{task_id, computed_score, override_score|null,
|
|
221
|
-
override_reason|null, model, effort, spawned_at}`. Feeds the usage report at
|
|
222
|
-
every stop.
|
|
1
|
+
# Reference — Effort, Dispatch Style, and Task Scoring
|
|
2
|
+
|
|
3
|
+
**Subagents ALWAYS do the work — the orchestrator never implements** (hard
|
|
4
|
+
rule 1). The orchestrator is Opus 4.8 high: it doing implementation is the most
|
|
5
|
+
costly way possible, and it burns the context that must survive the whole run.
|
|
6
|
+
Spawning keeps orchestrator context lean so runs last longer before any pause.
|
|
7
|
+
|
|
8
|
+
Two INDEPENDENT axes. Never conflate them:
|
|
9
|
+
- **Run-level effort** (low/medium/high) → picks the **dispatch style**
|
|
10
|
+
(sequential vs parallel), which controls only **intra-wave concurrency** —
|
|
11
|
+
never WHO does the work, and never WHETHER waves exist.
|
|
12
|
+
- **Per-task score** (0–100) → picks each **worker's model**. Always applies.
|
|
13
|
+
|
|
14
|
+
A medium run can contain a 30-score task and a 95-score task in the same wave.
|
|
15
|
+
|
|
16
|
+
## Waves always exist; dispatch style is intra-wave only
|
|
17
|
+
|
|
18
|
+
**Wave computation runs for every run with ≥2 tasks, sequential included**
|
|
19
|
+
(dependency layers + conflict graph + `max_wave_tasks` cap — see
|
|
20
|
+
`wave-grouping.md`). Dispatch style does NOT decide whether there are waves; it
|
|
21
|
+
decides how a wave's tasks fire:
|
|
22
|
+
|
|
23
|
+
- **sequential** → a wave's tasks dispatch one at a time, in order; the wave
|
|
24
|
+
closes when all its tasks close;
|
|
25
|
+
- **parallel** → a wave's non-conflicting tasks dispatch at once (up to
|
|
26
|
+
`max_wave_tasks`).
|
|
27
|
+
|
|
28
|
+
The **wave-boundary batch pause binds to wave numbers, identically in both
|
|
29
|
+
styles** — a sequential run is NOT "no waves / per-task pauses". Show the wave
|
|
30
|
+
plan (wave → tasks → pause marks) to the user BEFORE wave 1 in both styles.
|
|
31
|
+
|
|
32
|
+
## Run-level effort → dispatch style (recommend, user confirms)
|
|
33
|
+
|
|
34
|
+
- **Low**, or heavy shared data/code → **sequential**: one scored subagent at a
|
|
35
|
+
time, in dependency order (still grouped into waves). Even a single trivial
|
|
36
|
+
task = one cheap subagent (typically Sonnet 5 low), never the
|
|
37
|
+
orchestrator itself.
|
|
38
|
+
- **Medium** → sequential by default; **parallel** intra-wave if 3+ genuinely
|
|
39
|
+
independent areas.
|
|
40
|
+
- **High** with independent areas → **parallel** waves; consider worktrees for
|
|
41
|
+
isolation (merge at end).
|
|
42
|
+
|
|
43
|
+
Always RECOMMEND with a one-line why, and let the user pick. Tell them the
|
|
44
|
+
agent/task/wave counts, each task's scored model, and where batch pauses fall
|
|
45
|
+
BEFORE dispatching.
|
|
46
|
+
|
|
47
|
+
## Per-task scoring — facet-scored, arithmetic, two-writer
|
|
48
|
+
|
|
49
|
+
The score is **not judged** from a task title. The **planner** — the one party
|
|
50
|
+
that globbed and read every declared file — emits per-task `facets` (facts). The
|
|
51
|
+
**orchestrator** — who never read the code — computes the number arithmetically
|
|
52
|
+
and audits the facts. No vibes anywhere. Every task is scored, including tiny ones.
|
|
53
|
+
|
|
54
|
+
**1. Planner-emitted facets** (`planning-output.md` `facets` block, filled during
|
|
55
|
+
grounding — zero extra passes):
|
|
56
|
+
|
|
57
|
+
| Facet | Values |
|
|
58
|
+
|---|---|
|
|
59
|
+
| `breadth` | `len(declared_files)` — computed, not judged |
|
|
60
|
+
| `novelty` | mechanical · imitate · new-surface · novel-algorithm |
|
|
61
|
+
| `logic` | none · branching · stateful · algorithmic |
|
|
62
|
+
| `test_surface` | none · update-existing · new-tests |
|
|
63
|
+
| `risk` | `[]` or `[{class, cite}]` — class ∈ auth·money·migration·security·concurrency·data-integrity; **each entry MUST cite the file/requirement** |
|
|
64
|
+
| `uncertainty` | low · medium · high (+ one-line reason if not low) |
|
|
65
|
+
|
|
66
|
+
`fan_in`/`fan_out` are NOT emitted — the orchestrator computes them from
|
|
67
|
+
`depends_on` (forward = fan_in, reverse = fan_out).
|
|
68
|
+
|
|
69
|
+
**2. Orchestrator validation gate (Phase 2, deterministic — same bounce
|
|
70
|
+
mechanics as grounding):** emit `GATE facet pass|bounce`. Three checks:
|
|
71
|
+
|
|
72
|
+
- **Recompute** `breadth` (= `len(declared_files)`) and `fan_in`/`fan_out` from
|
|
73
|
+
the plan itself — a mismatch bounces.
|
|
74
|
+
- **MEMBERSHIP (v0.34.4):** `novelty`, `logic`, `test_surface` and `uncertainty`
|
|
75
|
+
must each be a member of their CLOSED set above, and every `risk[].class` must
|
|
76
|
+
be one of the six risk classes. A set lookup, as deterministic as the grounding
|
|
77
|
+
Glob. This is the check that was missing: the gate validated only the two
|
|
78
|
+
facets it could recompute and TRUSTED the four it could not, so a planner that
|
|
79
|
+
invented a `low|medium|high` scale produced an **arithmetically unscorable**
|
|
80
|
+
plan that passed the stated gate. There is no `N("low")` — and an orchestrator
|
|
81
|
+
applying `risk != [] -> floor 70` to prose risk strings floors EVERY task, a
|
|
82
|
+
two-band overshoot caused by a field's shape rather than by the work.
|
|
83
|
+
- **Cite check:** a `risk` entry with no `cite` bounces (unchanged).
|
|
84
|
+
|
|
85
|
+
A facet-vocabulary miss is a **FIELD-SHAPE bounce**: hand back the miss list and
|
|
86
|
+
say *do not re-plan* — the planner corrects only the offending `facets` blocks.
|
|
87
|
+
(It may also legitimately DROP a risk entry on the correction pass: implementation
|
|
88
|
+
hazards like test seeding or dependency discipline are not risk CLASSES. That
|
|
89
|
+
judgment is the planner's to make and is worth accepting.) Without this clause a
|
|
90
|
+
shape bounce risks costing a correct plan. A plan with no `facets` at all
|
|
91
|
+
(pre-v0.31.0) resumes on the legacy path — never bounced for the missing block.
|
|
92
|
+
|
|
93
|
+
**3. The fixed formula (the ONLY scoring text — this replaces base+adjusters):**
|
|
94
|
+
|
|
95
|
+
```
|
|
96
|
+
score = B(breadth) + N(novelty) + L(logic) + T(test_surface)
|
|
97
|
+
+ 5*min(fan_in,3) + 3*min(fan_out,3) + U(uncertainty)
|
|
98
|
+
|
|
99
|
+
B: 1f=2 2-3f=6 4-5f=10 6+f=15
|
|
100
|
+
N: mechanical=0 imitate=8 new-surface=18 novel-algorithm=30
|
|
101
|
+
L: none=0 branching=8 stateful=16 algorithmic=24
|
|
102
|
+
T: none=0 update-existing=4 new-tests=8
|
|
103
|
+
U: low=0 medium=6 high=12
|
|
104
|
+
|
|
105
|
+
risk ≠ [] → floor 70 (DERIVED from a cited risk facet, never remembered).
|
|
106
|
+
clamp 0..100 → the RESOLVED table (below).
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
**Which table (highest wins):** `opus5_only: true` (the 2-band Opus-5-only
|
|
110
|
+
preset: `[0,90)` low · `[90,100]` medium) → `rubric_bands_override`
|
|
111
|
+
(hand-written rows) → the default 5-band table. All three are in `config.md`.
|
|
112
|
+
The formula, the facets and the risk floor are IDENTICAL in every case — only
|
|
113
|
+
the score→agent mapping changes. Three consequences worth stating so nobody
|
|
114
|
+
re-derives them per run:
|
|
115
|
+
|
|
116
|
+
- **The risk floor still applies** — it raises the SCORE, then the resolved table
|
|
117
|
+
maps it. A floored task (≥70) lands `opus-5-low` in the default table and
|
|
118
|
+
`opus-5-low` under the Opus-5-only preset too: since v1.0.0 both tables answer
|
|
119
|
+
the floor with the same agent, and only a score of 90+ moves it to `opus-5-med`.
|
|
120
|
+
- **`opus5_only` FORCES** — while on, a hand-written `rubric_bands_override` is
|
|
121
|
+
ignored. It is the one selector that can shadow another; that is deliberate.
|
|
122
|
+
|
|
123
|
+
Show the user the full table (task, the facet vector, the arithmetic
|
|
124
|
+
`B+N+L+T+fan+U = raw`, any risk floor, final, override+reason if any, dispatched
|
|
125
|
+
model) BEFORE dispatching — an un-shown number is not a scored number. **Head it
|
|
126
|
+
with the RESOLVED table's name** (`5-band default` / `Opus-5-only ladder
|
|
127
|
+
(opus5_only)` / `custom (rubric_bands_override)`): the same logic
|
|
128
|
+
applies to the mapping as to the number.
|
|
129
|
+
|
|
130
|
+
**Extra (v0.50.0, `extra_enabled`) adds a `via` column and can make the head a
|
|
131
|
+
PAIR.** An Extra route row is an OVERLAY that outranks the tables above **only
|
|
132
|
+
for the scores it covers**, so a run can genuinely be running two tables at once
|
|
133
|
+
and the head names both (`5-band default + extra rows [0,30) [30,70)`). The
|
|
134
|
+
column reads `claude` or `extra:<profile> (<engine>)` and comes from
|
|
135
|
+
`orc extra resolve --json` — the formula, the facets and the risk floor are
|
|
136
|
+
untouched, and **the score is computed before the routing, never after it**. Two
|
|
137
|
+
consequences the table has to show rather than imply: a cited `risk[]` HOLDS THE
|
|
138
|
+
TASK BACK to its Claude band whatever the row says (`extra_risk_tasks: off`), and
|
|
139
|
+
the `model` for a foreign task is the FOREIGN model id, not a Claude tier.
|
|
140
|
+
Canonical: `../../_shared/extra-dispatch.md`.
|
|
141
|
+
|
|
142
|
+
**4. Consistency check:** two tasks whose facet vectors differ in **≤1 facet must
|
|
143
|
+
land in the same band** — or the SCORE line for the outlier **cites the one
|
|
144
|
+
differing facet**. This is the specific fix for sibling tasks in the same domain
|
|
145
|
+
drifting into three different bands.
|
|
146
|
+
|
|
147
|
+
**5. Override protocol** (unchanged): you may override the computed score. Record
|
|
148
|
+
`{computed_score, override_score, reason}` in the dispatch log. An override
|
|
149
|
+
without a reason is invalid.
|
|
150
|
+
|
|
151
|
+
## EVERY dispatch is scored — the fix-cycle rule
|
|
152
|
+
|
|
153
|
+
Fix-cycle dispatches — review-fix, verify-fix, the Phase-7 P2-batch, and any
|
|
154
|
+
requeue — are scored through the **same formula**, with two floors that stop a
|
|
155
|
+
fix in a risk area from silently dropping to a cheap model:
|
|
156
|
+
|
|
157
|
+
- **Inherit the ORIGINAL task's `risk` facets** when the fix touches its files —
|
|
158
|
+
a fix in a risk-floor area keeps the ≥70 floor (a userID/context-key fix can
|
|
159
|
+
never dispatch below `opus-5-low` again);
|
|
160
|
+
- a **P0/P1 fix never dispatches below the band of the task that produced the
|
|
161
|
+
finding.**
|
|
162
|
+
|
|
163
|
+
Emit a `SCORE task=fix-<n> …` line for each (they appear in the dispatch log and
|
|
164
|
+
the completion table like any task).
|
|
165
|
+
|
|
166
|
+
## Worked scoring examples (facet vectors — compare facet-by-facet, not by vibes)
|
|
167
|
+
|
|
168
|
+
Each row is the facet vector run through the formula. The number is arithmetic;
|
|
169
|
+
the band is what matters. Compare a new task to these facet-by-facet.
|
|
170
|
+
|
|
171
|
+
| Task | breadth·novelty·logic·test · fan_in/out · unc | Arithmetic | Band |
|
|
172
|
+
|---|---|---|---|
|
|
173
|
+
| Rename a config key across 4 files + its test | 5·mechanical·none·update-existing · 0/0 · low | 10+0+0+4 = **14** | sonnet-5-low [0,21) |
|
|
174
|
+
| New CRUD endpoint following a sibling route | 3·imitate·branching·new-tests · 1/0 · low | 6+8+8+8+5 = **35** | sonnet-5-high [31,41) |
|
|
175
|
+
| Bug fix across 2 files with a repro test | 3·imitate·branching·new-tests · 0/0 · medium | 6+8+8+8+6 = **36** | sonnet-5-high [31,41) |
|
|
176
|
+
| Isolated component from the design system | 3·new-surface·branching·new-tests · 0/0 · low | 6+18+8+8 = **40** | sonnet-5-high [31,41) |
|
|
177
|
+
| Notification model + enum other tasks consume | 3·new-surface·stateful·new-tests · 0/3 · low | 6+18+16+8+9 = **57** | opus-5-low [41,90) |
|
|
178
|
+
| Service-layer refactor behind a stable interface | 5·imitate·stateful·update-existing · 0/3 · medium | 10+8+16+4+9+6 = **53** | opus-5-low [41,90) |
|
|
179
|
+
| Add role check to payment-refund endpoint | 3·imitate·branching·new-tests · 0/0 · low · **risk=[auth,money]** | 30 raw → **floor 70** | opus-5-low [41,90) |
|
|
180
|
+
| Migrate orders table to split-name + backfill | 6·new-surface·stateful·new-tests · 1/3 · high · **risk=[migration,data-integrity]** | 15+18+16+8+5+9+12 = 83 (floor 70) → **83** | opus-5-low [41,90) |
|
|
181
|
+
|
|
182
|
+
Two disciplines the vectors encode: (1) a small diff is NOT a low score when a
|
|
183
|
+
cited `risk` facet forces the floor (the refund row — 30 raw, floored to 70); (2)
|
|
184
|
+
a big-looking task IS low when its facets are mechanical (the rename). The risk
|
|
185
|
+
floor is always DERIVED from a cited facet — the SCORE line names it, never
|
|
186
|
+
applies it silently.
|
|
187
|
+
|
|
188
|
+
## Model ladder → the single score→model table
|
|
189
|
+
|
|
190
|
+
The score→model mapping is NOT hardcoded here — it lives in `config.md` as ONE
|
|
191
|
+
canonical 5-band table (there is no longer a narrow/wide preset). Read config at
|
|
192
|
+
run start and map each task's final score through that table (or
|
|
193
|
+
`rubric_bands_override`). The orchestrator dispatches the executor agent BY NAME;
|
|
194
|
+
it does not request a raw model. `rubric_bands` sets only how many bands the
|
|
195
|
+
rubric REPORTS (score granularity), never which table is used.
|
|
196
|
+
|
|
197
|
+
The 5 bands (see config.md for the exact edges): `sonnet-5-low` [0,21) ·
|
|
198
|
+
`sonnet-5-med` [21,31) · `sonnet-5-high` [31,41) · `opus-5-low` [41,90) ·
|
|
199
|
+
`opus-5-med` [90,100]. Effort tiers rank
|
|
200
|
+
`low < medium < high < xhigh < max`.
|
|
201
|
+
|
|
202
|
+
## Fixed model assignments (not scored)
|
|
203
|
+
|
|
204
|
+
- **Orchestrator (you):** Opus 4.8 high — or Opus 5.5 / Fable 5 at medium+, the
|
|
205
|
+
two models that clear the guard from medium up. Never downgrade yourself.
|
|
206
|
+
- **Review** — Superpowers path: Sonnet 4.6, medium. OpenSpec/self path:
|
|
207
|
+
Opus 5.5, low (`orc-reviewer-opus-5-low`; medium until v2.1.0).
|
|
208
|
+
- **Verify:** Opus 5.5, medium (`orc-verifier-opus-5-med`).
|
|
209
|
+
- **Analyst:** Opus 5.5, high. **Planner:** Opus 5.5, medium. **Test author:**
|
|
210
|
+
Opus 5.5, medium. **Combiner:** Opus 5.5, high. **Ultra advisor/judge:** Opus 5.5,
|
|
211
|
+
xhigh — every core fixed role is pinned to Opus 5.5 as of v0.34.0.
|
|
212
|
+
- **Merge-conflict resolver:** Opus 4.8, medium.
|
|
213
|
+
|
|
214
|
+
Note: every band in the table above is a real dispatch target (sonnet-5 through
|
|
215
|
+
opus-5). If a model tier is unavailable in the environment, fall back UP to the
|
|
216
|
+
next capable tier (never silently substitute a different family/effort).
|
|
217
|
+
|
|
218
|
+
## Dispatch log (lives in the checkpoint)
|
|
219
|
+
|
|
220
|
+
Every spawn records: `{task_id, computed_score, override_score|null,
|
|
221
|
+
override_reason|null, model, effort, spawned_at}`. Feeds the usage report at
|
|
222
|
+
every stop.
|
|
@@ -50,6 +50,9 @@ open_questions: [object] # [] or [{question, proposed_default, blocking: bool}
|
|
|
50
50
|
declared_files: [string] # HARD GATE: actual files it will touch, incl. tests.
|
|
51
51
|
# File-level globs. No declaration → no wave assignment.
|
|
52
52
|
depends_on: [string] # forward = ordering; reverse = stale_review flagging
|
|
53
|
+
precedent: [string] # OPTIONAL. Read-only files this task copies behaviour
|
|
54
|
+
# or style from (max 5); the lane passes them to the
|
|
55
|
+
# pack as `--refs=`. Absent = the map picks them.
|
|
53
56
|
|
|
54
57
|
# grounding attestation (filled by the PLANNER — one entry per declared path)
|
|
55
58
|
grounding: [object] # {path, disposition: exists|new, evidence}
|
|
@@ -144,22 +144,22 @@ preflight line and has no gate to honour.
|
|
|
144
144
|
## Calls
|
|
145
145
|
|
|
146
146
|
**ONE catalogue, and it is not you:** `orc lane calls orc-aftermath --json` names every
|
|
147
|
-
CLI call this lane makes, each with its exit-code contract, its cost, when to run
|
|
147
|
+
SHARED CLI call this lane makes, each with its exit-code contract, its cost, when to run
|
|
148
148
|
it, and what an EMPTY answer means. Never invent a spelling, never re-word an
|
|
149
149
|
exit code, and never re-derive a state word — the CLI's state words are the only
|
|
150
150
|
state words, and **an exit code is an ANSWER wherever that contract says so, not
|
|
151
|
-
a failure**. A call
|
|
151
|
+
a failure**. A call that neither it nor this skill names is a call this lane does not make.
|
|
152
152
|
Exit ≠ 0 from the catalogue itself → say the CLI is unavailable and name the
|
|
153
|
-
command you are about to run, out loud, before running it.
|
|
154
|
-
|
|
155
|
-
## Rules — the anti-slop card (`../_shared/phases/rules.md`)
|
|
156
|
-
|
|
157
|
-
`orc rules slice --lane orc-aftermath --json` is the ONLY assembler; never build
|
|
158
|
-
the card here. It rides under the house rules and above the task —
|
|
159
|
-
**house rules > your project's rules > ORC's own packs** — and its `line` prints
|
|
160
|
-
VERBATIM at preflight. Returns gain `rules_applied[]`, `rules_conflicts[]` (a gap,
|
|
161
|
-
never a silent choice) and `rules_overridden[]`.
|
|
162
|
-
## Waiting mid-run (`/orc-wait`)
|
|
163
|
-
|
|
164
|
-
Canonical: `../_shared/wait.md`. **`a lane that waits without a hand-back` has broken this contract.**
|
|
165
|
-
Checkpoint **none** · safe point **read-only, seconds long**. Nothing here to checkpoint, so all three modes behave identically — say so rather than asking. Never begin a wait between a dispatch and its validated return, or before the smoke gate has reported.
|
|
153
|
+
command you are about to run, out loud, before running it.
|
|
154
|
+
|
|
155
|
+
## Rules — the anti-slop card (`../_shared/phases/rules.md`)
|
|
156
|
+
|
|
157
|
+
`orc rules slice --lane orc-aftermath --json` is the ONLY assembler; never build
|
|
158
|
+
the card here. It rides under the house rules and above the task —
|
|
159
|
+
**house rules > your project's rules > ORC's own packs** — and its `line` prints
|
|
160
|
+
VERBATIM at preflight. Returns gain `rules_applied[]`, `rules_conflicts[]` (a gap,
|
|
161
|
+
never a silent choice) and `rules_overridden[]`.
|
|
162
|
+
## Waiting mid-run (`/orc-wait`)
|
|
163
|
+
|
|
164
|
+
Canonical: `../_shared/wait.md`. **`a lane that waits without a hand-back` has broken this contract.**
|
|
165
|
+
Checkpoint **none** · safe point **read-only, seconds long**. Nothing here to checkpoint, so all three modes behave identically — say so rather than asking. Never begin a wait between a dispatch and its validated return, or before the smoke gate has reported.
|
|
@@ -210,8 +210,8 @@ exist). Menu rules, relatedness gate, combiner handling:
|
|
|
210
210
|
|
|
211
211
|
## Lane contract (`../_shared/lane-contract.md` — read it ONLY when a call exits ≠ 0)
|
|
212
212
|
|
|
213
|
-
- **Calls:** `orc lane calls orc-analyze --json` names
|
|
214
|
-
**An exit code is an ANSWER where it says so, not a failure.**
|
|
213
|
+
- **Calls:** `orc lane calls orc-analyze --json` names shared calls and exit codes.
|
|
214
|
+
**An exit code is an ANSWER where it says so, not a failure.** Own calls are here; make no other.
|
|
215
215
|
- **Config:** `orc lane config orc-analyze --json`. Obey `effective`, print every line
|
|
216
216
|
in `announce[]` VERBATIM at preflight, and honour `stops[]` before wave 1.
|
|
217
217
|
Never merge `.claude/orc.config.yaml` yourself (`../_shared/config-precedence.md`).
|
|
@@ -92,8 +92,8 @@ Never build or spawn.
|
|
|
92
92
|
|
|
93
93
|
## Lane contract (`../_shared/lane-contract.md` — read it ONLY when a call exits ≠ 0)
|
|
94
94
|
|
|
95
|
-
- **Calls:** `orc lane calls orc-analyze-mini --json` names
|
|
96
|
-
**An exit code is an ANSWER where it says so, not a failure.**
|
|
95
|
+
- **Calls:** `orc lane calls orc-analyze-mini --json` names shared calls and exit codes.
|
|
96
|
+
**An exit code is an ANSWER where it says so, not a failure.** Own calls are here; make no other.
|
|
97
97
|
- **Config:** `orc lane config orc-analyze-mini --json`. Obey `effective`. Never merge
|
|
98
98
|
`.claude/orc.config.yaml` yourself (`../_shared/config-precedence.md`). Nothing
|
|
99
99
|
here is contested, gated or a stop: no preflight line, no gate to honour.
|