omp-conductor 0.15.10 → 0.15.12

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 (92) hide show
  1. package/README.md +273 -2544
  2. package/REFERENCE.md +2680 -0
  3. package/package.json +3 -2
  4. package/schema/config.schema.json +11 -23
  5. package/src/arm-challenge.ts +112 -0
  6. package/src/ask.ts +434 -0
  7. package/src/board.ts +81 -15
  8. package/src/brief-upgrade.ts +114 -8
  9. package/src/briefs/orchestrator.md +113 -34
  10. package/src/briefs/policy.md +33 -8
  11. package/src/briefs/worker.md +18 -9
  12. package/src/chain-check.ts +1 -1
  13. package/src/check-trailing-newlines.ts +82 -0
  14. package/src/cli.ts +225 -1406
  15. package/src/commands/arm.ts +21 -0
  16. package/src/commands/board.ts +23 -0
  17. package/src/commands/brief-upgrade.ts +186 -0
  18. package/src/commands/context.ts +150 -0
  19. package/src/commands/daemon.ts +71 -0
  20. package/src/commands/dashboard.ts +74 -0
  21. package/src/commands/decision.ts +103 -0
  22. package/src/commands/disarm.ts +21 -0
  23. package/src/commands/doctor.ts +100 -0
  24. package/src/commands/event.ts +62 -0
  25. package/src/commands/extend.ts +64 -0
  26. package/src/commands/friction.ts +56 -0
  27. package/src/commands/help.ts +9 -0
  28. package/src/commands/hold.ts +26 -0
  29. package/src/commands/intake.ts +155 -0
  30. package/src/commands/ledger.ts +69 -0
  31. package/src/commands/message.ts +96 -0
  32. package/src/commands/report.ts +206 -0
  33. package/src/commands/restart.ts +76 -0
  34. package/src/commands/resume.ts +58 -0
  35. package/src/commands/setup.ts +143 -0
  36. package/src/commands/start.ts +23 -0
  37. package/src/commands/stats.ts +131 -0
  38. package/src/commands/status.ts +48 -0
  39. package/src/commands/stop.ts +51 -0
  40. package/src/commands/tail.ts +109 -0
  41. package/src/commands/unblock.ts +39 -0
  42. package/src/commands/upgrade-install.ts +31 -0
  43. package/src/commands/upgrade-rollback.ts +32 -0
  44. package/src/commands/upgrade.ts +25 -0
  45. package/src/commands/verb.ts +83 -0
  46. package/src/commands/version.ts +30 -0
  47. package/src/commands/worker.ts +100 -0
  48. package/src/config-schema.ts +47 -1
  49. package/src/config.ts +45 -4
  50. package/src/daemon.ts +972 -101
  51. package/src/dashboard/app.js +459 -0
  52. package/src/dashboard/index.html +61 -0
  53. package/src/dashboard/server.ts +481 -0
  54. package/src/dashboard/style.css +348 -0
  55. package/src/decisions.ts +39 -14
  56. package/src/diff-flags.ts +131 -241
  57. package/src/doctor.ts +932 -0
  58. package/src/escalate.ts +2 -2
  59. package/src/failure-class.ts +66 -3
  60. package/src/fleet.ts +58 -1
  61. package/src/gitops.ts +157 -0
  62. package/src/graph-health.ts +1 -1
  63. package/src/label-projection.ts +1 -1
  64. package/src/lifecycle.ts +198 -2
  65. package/src/model-fallback.ts +177 -0
  66. package/src/notices.ts +9 -0
  67. package/src/omp.ts +93 -13
  68. package/src/orchestrator-tick.ts +414 -20
  69. package/src/orchestrator.ts +4 -4
  70. package/src/privileged.ts +10 -0
  71. package/src/release-policy.ts +342 -30
  72. package/src/reports.ts +19 -5
  73. package/src/session-host.ts +11 -5
  74. package/src/setup-host.ts +663 -25
  75. package/src/setup-install.ts +292 -28
  76. package/src/setup-wizard.ts +255 -74
  77. package/src/setup.ts +156 -35
  78. package/src/stats.ts +331 -0
  79. package/src/store.ts +219 -22
  80. package/src/tracker/github.ts +74 -4
  81. package/src/types.ts +215 -31
  82. package/src/unblock.ts +55 -11
  83. package/src/upgrade-journal.ts +220 -0
  84. package/src/upgrade-verify.ts +506 -0
  85. package/src/upgrade.ts +385 -58
  86. package/src/verbs/actions.ts +73 -1
  87. package/src/verbs/protocol.ts +29 -4
  88. package/src/verbs/server.ts +183 -20
  89. package/src/worker.ts +3 -3
  90. package/systemd/omp-conductor-recover.sh +433 -0
  91. package/systemd/omp-conductor.service.example +14 -3
  92. package/systemd/recover-unit-test.sh +428 -0
@@ -24,17 +24,20 @@ cannot account for, and the checks that would have refused a bad push never ran.
24
24
  Reading with `gh` is fine; `git push`, `gh pr create` and `gh pr merge` are not
25
25
  yours to run.
26
26
 
27
- Read the issue first. **This brief is your copy of it**: the acceptance criteria
28
- below were rendered from the issue at dispatch, so you already have what you
29
- need. One `gh` read is still worth the call, for the discussion the brief did
30
- not copy down:
27
+ Read the issue first. **This brief is your copy of it**: the acceptance
28
+ criteria below were rendered from the issue at dispatch, and every comment on
29
+ it is rendered in the Discussion section. One `gh` read is still worth the
30
+ call, to compare the live issue against the copy in this brief:
31
31
 
32
32
  ```bash
33
- gh issue view {{ISSUE_NUMBER}} --repo {{TRACKER_REPO}} --comments
33
+ gh issue view {{ISSUE_NUMBER}} --repo {{TRACKER_REPO}} --json comments --jq '.comments[]|"@\(.author.login): \(.body)"'
34
34
  ```
35
35
 
36
- If that command fails, work from this brief and say so in your report rather
37
- than treating it as a blocker.
36
+ **If that command prints nothing, the read failed — say so in your report.**
37
+ `gh issue view --comments` prints nothing on a non-TTY while still exiting 0,
38
+ so empty output is never proof of an empty discussion. The Discussion section
39
+ below is what was read at dispatch; a live read that prints nothing while it
40
+ is there is a broken read, not a silent queue.
38
41
 
39
42
  Then read the repo's own guidance before writing anything: `AGENTS.md`,
40
43
  `CLAUDE.md`, `CONTEXT.md`, and any `docs/adr/` entry the issue touches. Those
@@ -44,7 +47,7 @@ files are canonical; your priors are not.
44
47
 
45
48
  {{ACCEPTANCE_CRITERIA}}
46
49
 
47
- ## How to work
50
+ {{ISSUE_COMMENTS}}## How to work
48
51
 
49
52
  1. **Understand before editing — and ask the graph before you grep.** Your turns
50
53
  are mostly spent finding code, not writing it, and running out of turns
@@ -213,10 +216,16 @@ pr: <url or "none">
213
216
  head: <40-character head SHA or "none">
214
217
  state: pushed-green | blocked | failed
215
218
  gates: <exact commands run and their results>
216
- changed: <files touched, one line>
219
+ changed: <the settlement derives this from the PR diff — omit the line>
217
220
  next: <nothing | the specific decision needed>
218
221
  ```
219
222
 
223
+ The `changed:` line is not yours to write from memory: the settlement replaces
224
+ it with the actual file list from the PR's diff. Omit it, or write it wrongly —
225
+ the settled report carries the diff's list either way. The narrative in your
226
+ report (what you changed and why, above these lines) is the part only you can
227
+ write, and it is the part a reviewer reads.
228
+
220
229
  Never report success you have not observed. "Should pass CI" is not a state, and
221
230
  `pushed-green` means you watched the checks go green — not that you expect them
222
231
  to.
@@ -154,4 +154,4 @@ export function chainViolations(input: ChainViolationInput): string[] {
154
154
  }
155
155
 
156
156
  return violations;
157
- }
157
+ }
@@ -0,0 +1,82 @@
1
+ /**
2
+ * Gate: tracked text files must end with a final newline and no trailing
3
+ * blank lines.
4
+ *
5
+ * Run via `bun run check` from the package root (after `tsc --noEmit`).
6
+ * Neither tsc nor the test suite has an opinion about the last byte of a
7
+ * file, so worker-authored files kept landing without one — each a spurious
8
+ * two-line hunk on the next edit. This is the cheap mechanical check that
9
+ * closes that gap: it walks `git ls-files`, checks every tracked text file
10
+ * by extension, and names every offender in a single run.
11
+ */
12
+
13
+ import { execFileSync } from "node:child_process";
14
+ import { readFileSync } from "node:fs";
15
+ import { join } from "node:path";
16
+
17
+ /** Tracked text suffixes the gate applies to. */
18
+ export const INCLUDED_SUFFIXES: readonly string[] = [
19
+ ".ts", ".js", ".css", ".html", ".md", ".json", ".yml", ".yaml", ".toml", ".sh",
20
+ ];
21
+
22
+ /**
23
+ * Generated files the gate must not police, named explicitly rather than
24
+ * guessed at by content. Paths are repo-root-relative, as `git ls-files`
25
+ * reports them.
26
+ */
27
+ export const EXCLUDED_PATHS: readonly string[] = [
28
+ "omp/bun.lock", // regenerated by `bun install`
29
+ "omp/schema/config.schema.json", // regenerated by `bun run schema`
30
+ ];
31
+
32
+ /** Reason this file's ending fails the gate, or null when it is correct. */
33
+ export function checkEnding(bytes: Uint8Array): string | null {
34
+ let trailingNewlines = 0;
35
+ for (let i = bytes.length - 1; i >= 0 && bytes[i] === 0x0a; i--) {
36
+ trailingNewlines++;
37
+ }
38
+ if (trailingNewlines === 0) return "missing trailing newline";
39
+ if (trailingNewlines > 2) return `ends with ${trailingNewlines - 1} blank lines`;
40
+ return null;
41
+ }
42
+
43
+ /**
44
+ * Check every file, returning one violation line per offender so a single
45
+ * run names every bad path instead of dying on the first.
46
+ */
47
+ export function findViolations(
48
+ paths: readonly string[],
49
+ read: (path: string) => Uint8Array = readFileSync,
50
+ ): string[] {
51
+ const violations: string[] = [];
52
+ for (const path of paths) {
53
+ const bytes = read(path);
54
+ if (bytes.length === 0) continue; // nothing to terminate
55
+ const reason = checkEnding(bytes);
56
+ if (reason !== null) violations.push(`${path}: ${reason}`);
57
+ }
58
+ return violations;
59
+ }
60
+
61
+ function repoRoot(): string {
62
+ return execFileSync("git", ["rev-parse", "--show-toplevel"], { encoding: "utf8" }).trim();
63
+ }
64
+
65
+ if (import.meta.main) {
66
+ const root = repoRoot();
67
+ const tracked = execFileSync("git", ["-C", root, "ls-files"], { encoding: "utf8" })
68
+ .split("\n")
69
+ .filter((path) => path.length > 0);
70
+ const textFiles = tracked.filter(
71
+ (path) =>
72
+ INCLUDED_SUFFIXES.some((suffix) => path.endsWith(suffix)) &&
73
+ !EXCLUDED_PATHS.includes(path),
74
+ );
75
+ const violations = findViolations(textFiles, (path) => readFileSync(join(root, path)));
76
+ if (violations.length > 0) {
77
+ for (const violation of violations) console.error(violation);
78
+ console.error(`trailing newline gate: ${violations.length} file(s) need fixing`);
79
+ process.exit(1);
80
+ }
81
+ console.log("trailing newline gate: ok");
82
+ }