@azure-id/orc 1.8.2 → 1.9.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.
Files changed (42) hide show
  1. package/CHANGELOG.md +166 -0
  2. package/README-id.md +69 -51
  3. package/README.md +62 -45
  4. package/bin/cli.js +76 -16
  5. package/bin/verify-contracts.js +163 -62
  6. package/bin/verify-package.js +15 -1
  7. package/mock-run/orc-quick.md +141 -113
  8. package/package.json +1 -1
  9. package/templates/agents/MODEL-MAPPING.md +15 -5
  10. package/templates/agents/orc-executor-haiku-4-5.md +17 -0
  11. package/templates/agents/orc-executor-opus-4-7-high.md +17 -0
  12. package/templates/agents/orc-executor-opus-4-7-med.md +17 -0
  13. package/templates/agents/orc-executor-opus-4-8-high.md +17 -0
  14. package/templates/agents/orc-executor-opus-5-high.md +17 -0
  15. package/templates/agents/orc-executor-opus-5-low.md +17 -0
  16. package/templates/agents/orc-executor-opus-5-med.md +17 -0
  17. package/templates/agents/orc-executor-sonnet-4-6-high.md +17 -0
  18. package/templates/agents/orc-executor-sonnet-4-6-med.md +17 -0
  19. package/templates/agents/orc-executor-sonnet-5-high.md +17 -0
  20. package/templates/agents/orc-planner-mini-opus-5-med.md +75 -69
  21. package/templates/agents/orc-planner-mini-sonnet-5-high.md +73 -67
  22. package/templates/agents/orc-recon-opus-5-low.md +99 -0
  23. package/templates/agents/orc-recon-sonnet-4-6-med.md +99 -0
  24. package/templates/commands/orc-mini.md +10 -12
  25. package/templates/commands/orc-quick.md +20 -33
  26. package/templates/hooks/orc-trace.js +476 -471
  27. package/templates/skills/_shared/phases/rules.md +172 -159
  28. package/templates/skills/_shared/phases/trace.md +2 -1
  29. package/templates/skills/_shared/phases/wiki-consult.md +9 -5
  30. package/templates/skills/_shared/return-validation.md +22 -0
  31. package/templates/skills/context-combiner/SKILL.md +13 -13
  32. package/templates/skills/orc/subskills/orc-execution/core.md +171 -159
  33. package/templates/skills/orc-mini/SKILL.md +148 -136
  34. package/templates/skills/orc-mini/examples/mini-run-mock.md +64 -50
  35. package/templates/skills/orc-mini/references/complexity.md +105 -0
  36. package/templates/skills/orc-quick/README.md +495 -423
  37. package/templates/skills/orc-quick/SKILL.md +157 -211
  38. package/templates/skills/orc-quick/references/context-doc.md +145 -114
  39. package/templates/skills/orc-quick/references/defect.md +101 -0
  40. package/templates/skills/orc-quick/references/dispatch-gate.md +55 -24
  41. package/templates/skills/orc-quick/references/gh-mode.md +148 -127
  42. package/templates/skills/orc-quick/references/look.md +107 -0
package/bin/cli.js CHANGED
@@ -3347,7 +3347,10 @@ const LANE_CALLS = {
3347
3347
  on_absent: "`none` means absent; say so in ONE user line and continue — a missing wiki is never a blocker",
3348
3348
  canonical: "_shared/detecting-artifacts.md",
3349
3349
  never: "never second-guess a positive probe with a raw `find` (the wiki lives under a dot-dir), and never compute the tier yourself — this command is its only executor",
3350
- lanes: ["orc", "orc-boundary", "orc-brainstorm", "orc-fast", "orc-grill", "orc-poly", "orc-quick", "orc-route", "orc-wiki"],
3350
+ // v1.9.0: /orc-mini joins. It always consulted the wiki; it now selects PAGE
3351
+ // PATHS for its slices instead of reading page bodies into its own context,
3352
+ // and the tier this command computes is what that selection rests on.
3353
+ lanes: ["orc", "orc-boundary", "orc-brainstorm", "orc-fast", "orc-grill", "orc-mini", "orc-poly", "orc-quick", "orc-route", "orc-wiki"],
3351
3354
  },
3352
3355
  "pattern-status": {
3353
3356
  cmd: "orc pattern status <lang>",
@@ -3423,11 +3426,11 @@ const LANE_CALLS = {
3423
3426
  exits: { 0: "answered \u2014 ALWAYS, when a graph exists", 1: "no graph index", 3: "off \u2014 `code_graph` is off" },
3424
3427
  states: null,
3425
3428
  cost: "free",
3426
- when: "ONCE, at the START of planning \u2014 before any Glob and before `impact`, which needs the files already chosen. Planning ONLY: DE-H gated the analyst and /orc-quick on M2 showing 3 or more answerable calls per run and it measured 0.39",
3429
+ when: "ONCE, at the START of planning \u2014 before any Glob and before `impact`, which needs the files already chosen. Planning ONLY, and v1.9.0 widens what counts as planning rather than the rule: /orc-quick's Q1 when the request NAMES NO FILE, and /orc-mini's intake before the tiered round, are the same question asked by a lane with no planner. DE-H's 0.39 answerable calls per run measured the analyst asking it AFTER the files were known, which is the case this row still refuses",
3427
3430
  on_absent: "exit 1 or 3 \u2192 orient with Glob and Read exactly as before the map existed",
3428
3431
  canonical: "_shared/code-graph.md",
3429
- never: "never read RANK as importance to THIS change \u2014 it is a hint about where to look first, computed from the whole repository, and a low-ranked file that the change reaches is still a file you must read",
3430
- lanes: ["orc", "orc-diy"],
3432
+ never: "never read RANK as importance to THIS change \u2014 it is a hint about where to look first, computed from the whole repository, and a low-ranked file that the change reaches is still a file you must read. Never call it a SECOND time in one run: the ranking does not move because you read it",
3433
+ lanes: ["orc", "orc-diy", "orc-mini", "orc-quick"],
3431
3434
  },
3432
3435
  "graph-impact": {
3433
3436
  cmd: "orc graph impact <file…> --if-enabled [--depth N] [--json]",
@@ -3439,7 +3442,7 @@ const LANE_CALLS = {
3439
3442
  on_absent: "exit 3 or 4 → plan or review exactly as before; AMBIGUOUS callers are counted, never followed",
3440
3443
  canonical: "_shared/code-graph.md",
3441
3444
  never: "never treat an empty impact as proof nothing depends on the change — dynamic dispatch is invisible to the graph",
3442
- lanes: ["orc", "orc-diy"],
3445
+ lanes: ["orc", "orc-diy", "orc-mini"],
3443
3446
  },
3444
3447
  // EW5 — the cheap signals. All three read what is already on disk (the index,
3445
3448
  // and git's own history), so all three cost zero model tokens.
@@ -3453,7 +3456,7 @@ const LANE_CALLS = {
3453
3456
  on_absent: "exit 1 or 3 → read the source, exactly as before the graph existed",
3454
3457
  canonical: "_shared/code-graph.md",
3455
3458
  never: "never read `no recorded gap` as proof of completeness — a file marked `full` was fully PARSED, not fully understood",
3456
- lanes: ["orc", "orc-diy"],
3459
+ lanes: ["orc", "orc-diy", "orc-quick"],
3457
3460
  },
3458
3461
  "graph-changes": {
3459
3462
  cmd: "orc graph changes [--base <ref>] --if-enabled [--json]",
@@ -3465,7 +3468,7 @@ const LANE_CALLS = {
3465
3468
  on_absent: "exit 1 or 3 → review from the diff alone, exactly as before",
3466
3469
  canonical: "_shared/code-graph.md",
3467
3470
  never: "never report `risk` without the `why` beside it — a rating nobody can check is a rating nobody should act on",
3468
- lanes: ["orc", "orc-diy"],
3471
+ lanes: ["orc", "orc-diy", "orc-mini", "orc-quick"],
3469
3472
  },
3470
3473
  "graph-cochange": {
3471
3474
  cmd: "orc graph cochange <file> --if-enabled [--json]",
@@ -3477,7 +3480,19 @@ const LANE_CALLS = {
3477
3480
  on_absent: "exit 4 is an ANSWER, not a miss — plan exactly as before",
3478
3481
  canonical: "_shared/code-graph.md",
3479
3482
  never: "never read a co-change as a DEPENDENCY — it says what people changed together, never what needs what",
3480
- lanes: ["orc", "orc-diy"],
3483
+ lanes: ["orc", "orc-diy", "orc-mini"],
3484
+ },
3485
+ "graph-gain": {
3486
+ cmd: "orc graph gain --run <trace name> --if-enabled [--json]",
3487
+ what: "what the graph cost this run and what it plausibly avoided — three halves kept apart: paid (recorded) · avoided (an ESTIMATE, always a range) · measured (silent below three runs per group)",
3488
+ exits: { 0: "a line", 1: "no ledger, or no rows yet", 3: "off" },
3489
+ states: null,
3490
+ cost: "free",
3491
+ when: "ONCE, at the close of a code-writing request (quick) or after a green smoke gate (mini)",
3492
+ on_absent: "exit 1 is an ANSWER — there is nothing to report yet, so report nothing",
3493
+ canonical: "_shared/code-graph.md",
3494
+ never: "never restate the line as a saving, never drop the word estimate or the range, and never let this call block or fail a run",
3495
+ lanes: ["orc-mini", "orc-quick"],
3481
3496
  },
3482
3497
  "graph-notes-pending": {
3483
3498
  cmd: "orc graph notes pending --files <a,b> [--at wave|end] --if-enabled [--json]",
@@ -3489,7 +3504,11 @@ const LANE_CALLS = {
3489
3504
  on_absent: "exit 5 is an ANSWER — the symbols wait for a later batch and nothing is lost",
3490
3505
  canonical: "_shared/code-graph.md",
3491
3506
  never: "never paste notes into your own context — the noter pipes them to `orc graph notes apply -` and returns one line",
3492
- lanes: ["orc", "orc-diy", "orc-fast", "orc-mini", "orc-quick"],
3507
+ // v1.9.0: /orc-quick and /orc-mini left this row. Neither lost the notes —
3508
+ // both stopped making a SECOND call for them: each now runs
3509
+ // `update --notes-pending`, which answers the update and the pending batch
3510
+ // in one, and still dispatches the noter when the answer has rows.
3511
+ lanes: ["orc", "orc-diy", "orc-fast"],
3493
3512
  },
3494
3513
  "gotcha-list": {
3495
3514
  cmd: "orc gotcha list [--archived] [--json]",
@@ -4415,10 +4434,14 @@ const LANE_OWN_PHASES = {
4415
4434
  { ord: 6, id: "phase-s6", file: "orc-pr-setup/SKILL.md", heading: "## Phase S6 — Emit the plan, then stop", read: "section", trace_verbs: [] },
4416
4435
  ],
4417
4436
  "orc-quick": [
4418
- { ord: 0, id: "q0", file: "orc-quick/SKILL.md", heading: "## Q0 — Preflight (ONE time per session, silent, nothing can stop the run)", read: "section", trace_verbs: ["GATE"] },
4419
- { ord: 1, id: "q1", file: "orc-quick/SKILL.md", heading: "## Q1 — LOOK (silent — no questions here)", read: "section", trace_verbs: ["GATE", "WIKI-CONSULT"] },
4437
+ // v1.9.0 — the verbs the lane already owed, plus the graph-first look and
4438
+ // the defect reproduction. The HEADINGS are unchanged: a `read: section`
4439
+ // pointer names a heading byte-for-byte, and a payload test asserts each
4440
+ // one still exists in the spine.
4441
+ { ord: 0, id: "q0", file: "orc-quick/SKILL.md", heading: "## Q0 — Preflight (ONE time per session, silent, nothing can stop the run)", read: "section", trace_verbs: ["GATE", "GRAPH-CONSULT"] },
4442
+ { ord: 1, id: "q1", file: "orc-quick/SKILL.md", heading: "## Q1 — LOOK (silent — no questions here)", read: "section", trace_verbs: ["GATE", "WIKI-CONSULT", "GRAPH-CONSULT", "GRAPH-MAP"] },
4420
4443
  { ord: 2, id: "q2", file: "orc-quick/SKILL.md", heading: "## Q2 — ASK (ONE user turn: questions + the gate together)", read: "section", trace_verbs: [] },
4421
- { ord: 3, id: "q3", file: "orc-quick/SKILL.md", heading: "## Q3 — DO (dispatch → build/test → write the doc → offer)", read: "section", trace_verbs: ["FINISH", "OUTCOME", "VERIFY"] },
4444
+ { ord: 3, id: "q3", file: "orc-quick/SKILL.md", heading: "## Q3 — DO (dispatch → build/test → write the doc → offer)", read: "section", trace_verbs: ["DISPATCH", "VERIFY", "REPRO", "GRAPH-CHANGES", "GRAPH-UPDATE", "GRAPH-NOTES", "GRAPH-GAIN", "OUTCOME", "FINISH"] },
4422
4445
  ],
4423
4446
  "orc-wiki": [
4424
4447
  { ord: 0, id: "phase-0", file: "orc-wiki/references/phases/phase-0.md", layers: ["full"], trace_verbs: [] },
@@ -4514,6 +4537,9 @@ const PHASE_KIND = {
4514
4537
  combine: "look",
4515
4538
  // waiting on the user
4516
4539
  intake: "ask",
4540
+ // v1.9.0 — /orc-quick's read-only half. It LOOKS: one question, answered
4541
+ // with evidence, and nothing written.
4542
+ recon: "look",
4517
4543
  // deciding what to do and in what order
4518
4544
  planning: "plan",
4519
4545
  "plan-handoff": "plan",
@@ -4593,7 +4619,7 @@ function railKind(row) {
4593
4619
  // This is a MIRROR of that hook's `roleFamily()`, and it is the one new drift
4594
4620
  // surface this feature adds — a golden test compares the two by source text,
4595
4621
  // the way the `OPUS5_BANDS` alias is asserted.
4596
- const TRACE_FAMILIES = ["combine", "analysis", "planning", "execution", "review", "verify", "testgen", "ultra-gate"];
4622
+ const TRACE_FAMILIES = ["recon", "combine", "analysis", "planning", "execution", "review", "verify", "testgen", "ultra-gate"];
4597
4623
 
4598
4624
  // The whole object, deterministic from the registries above. `--json is not a
4599
4625
  // summary`: this is what the file holds and what `orc lane rails` prints.
@@ -44482,6 +44508,29 @@ function rulesLine(packs, blocks, overrides) {
44482
44508
  // body and PURPOSE/LOCK rules carry one line each plus the file to open when one
44483
44509
  // applies. That is the read-ladder discipline this repo already runs on, applied
44484
44510
  // to a standing card.
44511
+ // v1.9.0 - the COMPACT form, and the CLI decides it, never the lane.
44512
+ // `_shared/phases/rules.md` names `rulesSlice()` as the only lever on the
44513
+ // card's cost, so a lane that wanted a smaller card had no honest way to ask
44514
+ // for one. /orc-quick is the lane with the SMALLEST tasks under the LARGEST
44515
+ // fixed card: the full card measured 13,874 chars, re-sent on every executor
44516
+ // turn, for a task that often edits one file. Compact keeps every HARD rule's
44517
+ // ID and its first line - the instruction - and drops the worked examples,
44518
+ // which are what a rule's body is mostly made of. Nothing is hidden: the pack
44519
+ // file is named beside the rules, exactly as the light tiers already are.
44520
+ const RULES_COMPACT_LANES = new Set(["orc-quick"]);
44521
+
44522
+ // One line out of a rule body: the first paragraph, whitespace collapsed, cut
44523
+ // at a word boundary. A rule whose instruction does not survive that is a rule
44524
+ // whose body is an example, and the pack file is one Read away.
44525
+ function rulesOneLine(body, max) {
44526
+ const first = String(body || "").split(/\n[ \t]*\n/)[0] || "";
44527
+ const flat = first.replace(/\s+/g, " ").trim();
44528
+ if (flat.length <= max) return flat;
44529
+ const cut = flat.slice(0, max);
44530
+ const at = cut.lastIndexOf(" ");
44531
+ return (at > max * 0.6 ? cut.slice(0, at) : cut).replace(/[ ,;:.]+$/, "") + " …";
44532
+ }
44533
+
44485
44534
  function rulesSlice(claudeDir, lane, extraPacks) {
44486
44535
  const packs = rulesReadPacks(claudeDir);
44487
44536
  const led = userRulesRead(claudeDir);
@@ -44489,6 +44538,7 @@ function rulesSlice(claudeDir, lane, extraPacks) {
44489
44538
  const overridden = new Set(overrides.filter((o) => o.known).map((o) => o.id));
44490
44539
  const want = new Set([...(RULE_LANE_PACKS[lane] || []), ...(extraPacks || [])]);
44491
44540
  const chosen = packs.packs.filter((p) => want.has(p.id));
44541
+ const compact = RULES_COMPACT_LANES.has(lane);
44492
44542
 
44493
44543
  const L = [];
44494
44544
  if (!led.empty) {
@@ -44501,19 +44551,26 @@ function rulesSlice(claudeDir, lane, extraPacks) {
44501
44551
  if (chosen.length) {
44502
44552
  L.push(
44503
44553
  `ORC RULES — the anti-slop baseline. Shipped with ORC, read-only. ${packs.count} rules, ${plural(chosen.length, "pack")} in this slice.`,
44504
- "Source: petergyang/no-ai-slop · miqdadbadjuber/anti-slop · ehmo/slopkit · BioInfo/slopless · Karpathy · Matty Cartwright. Full credits: `orc rules credits`.",
44554
+ // The credits line is a CREDIT, not an instruction, and `orc rules
44555
+ // credits` prints it in full. It is the one line a compact card can drop
44556
+ // without dropping a rule.
44557
+ ...(compact ? [] : ["Source: petergyang/no-ai-slop · miqdadbadjuber/anti-slop · ehmo/slopkit · BioInfo/slopless · Karpathy · Matty Cartwright. Full credits: `orc rules credits`."]),
44505
44558
  "HARD = absolute · PURPOSE = allowed with a written one-line reason · LOCK = consistency, reported never blocking.",
44559
+ ...(compact ? ["Each line below is a rule ID and its instruction. Credits: `orc rules credits`."] : []),
44506
44560
  ""
44507
44561
  );
44508
44562
  for (const p of chosen) {
44509
44563
  L.push(`[${p.title}]`);
44510
44564
  for (const r of p.rules) {
44511
44565
  if (overridden.has(r.id)) continue; // the user replaced it
44512
- if (r.tier === "HARD") L.push(`${r.id} HARD · ${r.title}`, r.body, "");
44566
+ if (r.tier === "HARD" && compact) L.push(`${r.id} HARD · ${r.title} — ${rulesOneLine(r.body, 62)}`);
44567
+ else if (r.tier === "HARD") L.push(`${r.id} HARD · ${r.title}`, r.body, "");
44513
44568
  else L.push(`${r.id} ${r.tier} · ${r.title}`);
44514
44569
  }
44515
44570
  const light = p.rules.filter((r) => r.tier !== "HARD" && !overridden.has(r.id)).length;
44516
- if (light) L.push("", `${plural(light, "rule")} above are one-liners — open ${p.file} when one of them applies.`, "");
44571
+ if (compact)
44572
+ L.push("", `Every rule above is one line — open ${p.file} for the body and the worked examples of any that applies.`, "");
44573
+ else if (light) L.push("", `${plural(light, "rule")} above are one-liners — open ${p.file} when one of them applies.`, "");
44517
44574
  }
44518
44575
  }
44519
44576
  if (overrides.length) {
@@ -44531,6 +44588,9 @@ function rulesSlice(claudeDir, lane, extraPacks) {
44531
44588
  return {
44532
44589
  lane,
44533
44590
  packs: chosen.map((p) => p.id),
44591
+ // `compact` is REPORTED, never asked for. A reader that cannot tell a short
44592
+ // card from a stripped one cannot trust either.
44593
+ compact,
44534
44594
  text: L.join("\n").replace(/\n{3,}/g, "\n\n").replace(/\s+$/, ""),
44535
44595
  overrides,
44536
44596
  line: rulesLine(packs, led.blocks, overrides),