omp-conductor 0.18.1 → 0.19.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 (69) hide show
  1. package/README.md +106 -41
  2. package/REFERENCE.md +866 -31
  3. package/agents/to-spec.md +6 -2
  4. package/package.json +1 -1
  5. package/schema/config.schema.json +32 -1
  6. package/src/admission.ts +212 -26
  7. package/src/arm-challenge.ts +250 -57
  8. package/src/ask.ts +288 -1
  9. package/src/briefs/orchestrator.md +27 -13
  10. package/src/briefs/to-spec.md +6 -2
  11. package/src/cli.ts +127 -2
  12. package/src/command-help.ts +9 -1
  13. package/src/command-manifest.ts +52 -8
  14. package/src/commands/arm.ts +6 -2
  15. package/src/commands/context.ts +2 -0
  16. package/src/commands/intake.ts +4 -19
  17. package/src/commands/message.ts +26 -2
  18. package/src/commands/reconcile-units.ts +104 -0
  19. package/src/commands/release-composition.ts +232 -0
  20. package/src/commands/resume.ts +2 -27
  21. package/src/commands/setup.ts +101 -16
  22. package/src/commands/stats.ts +11 -30
  23. package/src/commands/tail.ts +31 -1
  24. package/src/commands/upgrade.ts +20 -3
  25. package/src/commands/verb.ts +2 -1
  26. package/src/commands/watch.ts +4 -17
  27. package/src/config-schema.ts +38 -6
  28. package/src/config.ts +103 -8
  29. package/src/credential-class.ts +366 -0
  30. package/src/daemon.ts +1368 -529
  31. package/src/dashboard/app.js +504 -2
  32. package/src/dashboard/controls.ts +336 -0
  33. package/src/dashboard/index.html +30 -0
  34. package/src/dashboard/server.ts +271 -30
  35. package/src/dashboard/style.css +116 -0
  36. package/src/dashboard/transcript.ts +173 -0
  37. package/src/decisions.ts +19 -11
  38. package/src/doctor.ts +431 -148
  39. package/src/escalate.ts +22 -11
  40. package/src/failure-class.ts +59 -0
  41. package/src/fleet.ts +587 -230
  42. package/src/host.ts +6 -455
  43. package/src/omp-settings.ts +19 -0
  44. package/src/omp.ts +40 -56
  45. package/src/orchestrator-tick.ts +564 -121
  46. package/src/pause.ts +233 -0
  47. package/src/session-host.ts +6 -41
  48. package/src/settlement.ts +159 -2
  49. package/src/setup-answers.ts +97 -0
  50. package/src/setup-host.ts +343 -1160
  51. package/src/setup-install.ts +204 -27
  52. package/src/setup-wizard.ts +252 -51
  53. package/src/setup.ts +87 -4
  54. package/src/spend-telemetry.ts +117 -0
  55. package/src/stats.ts +35 -0
  56. package/src/status-render.ts +485 -19
  57. package/src/store.ts +1229 -55
  58. package/src/telegram-freshness.ts +269 -0
  59. package/src/to-spec.ts +50 -2
  60. package/src/types.ts +759 -10
  61. package/src/unblock.ts +22 -0
  62. package/src/unit-reconcile.ts +303 -0
  63. package/src/upgrade-verify.ts +8 -1
  64. package/src/upgrade.ts +299 -12
  65. package/src/verbs/actions.ts +124 -10
  66. package/src/verbs/protocol.ts +70 -2
  67. package/src/verbs/server.ts +485 -11
  68. package/src/wake.ts +48 -0
  69. package/src/worker.ts +401 -14
@@ -286,6 +286,14 @@ export const VERB_SPECS: Readonly<Record<VerbName, VerbSpec>> = {
286
286
  required: false,
287
287
  description: "Tag to prepare or cut, for version-bump-pr, git-tag, and github-release.",
288
288
  },
289
+ sha: {
290
+ type: "string",
291
+ required: false,
292
+ description:
293
+ "Pin the tag to this exact commit instead of whatever the released repo's default branch " +
294
+ "is at cut time (#695), for git-tag and git-push-tags. The commit must be reachable from " +
295
+ "that branch, or the release is refused naming it. Omit it and the behaviour is unchanged.",
296
+ },
289
297
  artefact: {
290
298
  type: "string",
291
299
  required: false,
@@ -371,6 +379,47 @@ export const VERB_SPECS: Readonly<Record<VerbName, VerbSpec>> = {
371
379
  roleRefusalText: (role) =>
372
380
  `review authority is the orchestrator's; this is a ${role} session, and a worker never returns its own PR for revision.`,
373
381
  },
382
+ conductor_pr_review_clear: {
383
+ name: "conductor_pr_review_clear",
384
+ mutating: true,
385
+ allowedRoles: ["orchestrator"],
386
+ description:
387
+ "Record that the durable review findings standing at one exact head are settled, so " +
388
+ "`conductor_pr_merge` stops refusing that head with merge-blocked-by-review (#913). This is the " +
389
+ "only clearance reachable at an UNCHANGED head: a re-review at the same head opens or appends to " +
390
+ "another blocking round rather than superseding one, and nothing settles a round from outside a " +
391
+ "worker. The clearance applies strictly backwards — it suppresses the evidence recorded up to the " +
392
+ "moment it is taken, never a finding recorded afterwards — and to that one head only. It bypasses " +
393
+ "nothing else: authority, pause, base-red-freeze, exact-head, green checks, release composition and " +
394
+ "single-flight all still apply to the merge. Refused for a PR no run of this project owns, a head " +
395
+ "that is not the live head, and a head where nothing is blocking.",
396
+ args: {
397
+ prUrl: {
398
+ type: "string",
399
+ required: true,
400
+ description:
401
+ "Full pull request URL — one a run of this project recorded, in a routed repository.",
402
+ },
403
+ headSha: {
404
+ type: "string",
405
+ required: true,
406
+ description:
407
+ "The exact head being cleared. Must equal the live head; checks are not re-read here " +
408
+ "(the merge gate re-checks green itself).",
409
+ },
410
+ reason: {
411
+ type: "string",
412
+ required: true,
413
+ description:
414
+ "Why this evidence is settled, in your own words. Non-empty, recorded verbatim in the " +
415
+ "ledger and the digest — this is the audit trail for a merge that a review round refused.",
416
+ },
417
+ rationale: RATIONALE_ARG,
418
+ },
419
+ roleRefusalText: (role) =>
420
+ `clearing review findings is the orchestrator's disposition; this is a ${role} session, ` +
421
+ "and a worker never clears the findings standing against its own pull request.",
422
+ },
374
423
  conductor_pr_recover: {
375
424
  name: "conductor_pr_recover",
376
425
  mutating: true,
@@ -570,13 +619,32 @@ export function parseVerbRequest(raw: unknown): VerbParse {
570
619
  if (arg.oneOf !== undefined && !arg.oneOf.some((allowed) => allowed === value)) {
571
620
  // `reason` is the field #129 closed on purpose, so it gets its own
572
621
  // refusal code: an out-of-enum reason is vocabulary drift, not a typo.
622
+ const reasonDrift = key === "reason";
623
+ // Measured on this fleet 2026-08-23: this is the largest single refusal
624
+ // cause in the ledger — 99 of 241, across the four verbs whose `reason`
625
+ // is a closed set, still firing. Every one of the 99 carried a real
626
+ // explanation ("landed directly in PR #940; queue label would re-dispatch
627
+ // finished work"), which is exactly the audit content the ledger exists
628
+ // to hold, and 7578 characters of it were discarded. None of the 99
629
+ // supplied `rationale` — the field built for it — because the moment a
630
+ // caller has a sentence to record is the moment they are told only that
631
+ // `reason` is closed (#968).
632
+ //
633
+ // Keyed on the spec rather than a hardcoded verb list: a verb with an
634
+ // enum `reason` and no `rationale` must not be told to use a field it
635
+ // would then refuse as `unknown-argument`, turning one wasted round trip
636
+ // into two.
637
+ const carriesRationale = reasonDrift && spec.args["rationale"] !== undefined;
573
638
  return {
574
639
  ok: false,
575
640
  verb,
576
- refusal: key === "reason" ? "reason-not-in-enum" : "malformed-argument",
641
+ refusal: reasonDrift ? "reason-not-in-enum" : "malformed-argument",
577
642
  detail:
578
643
  `refused: ${verb} argument "${key}" must be one of ${arg.oneOf.join(", ")}, ` +
579
- `got ${JSON.stringify(value)}.`,
644
+ `got ${JSON.stringify(value)}.` +
645
+ (carriesRationale
646
+ ? ' Pick the enum value that fits and put that sentence in "rationale", which is logged verbatim.'
647
+ : ""),
580
648
  };
581
649
  }
582
650
  }