instar 1.3.511 → 1.3.512

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/dist/commands/server.d.ts.map +1 -1
  2. package/dist/commands/server.js +67 -1
  3. package/dist/commands/server.js.map +1 -1
  4. package/dist/config/ConfigDefaults.d.ts.map +1 -1
  5. package/dist/config/ConfigDefaults.js +24 -0
  6. package/dist/config/ConfigDefaults.js.map +1 -1
  7. package/dist/core/CoherenceJournal.d.ts +31 -1
  8. package/dist/core/CoherenceJournal.d.ts.map +1 -1
  9. package/dist/core/CoherenceJournal.js +49 -2
  10. package/dist/core/CoherenceJournal.js.map +1 -1
  11. package/dist/core/JournalSyncApplier.d.ts.map +1 -1
  12. package/dist/core/JournalSyncApplier.js +18 -0
  13. package/dist/core/JournalSyncApplier.js.map +1 -1
  14. package/dist/core/PostUpdateMigrator.d.ts.map +1 -1
  15. package/dist/core/PostUpdateMigrator.js +44 -0
  16. package/dist/core/PostUpdateMigrator.js.map +1 -1
  17. package/dist/core/devGatedFeatures.d.ts.map +1 -1
  18. package/dist/core/devGatedFeatures.js +5 -0
  19. package/dist/core/devGatedFeatures.js.map +1 -1
  20. package/dist/core/types.d.ts +27 -0
  21. package/dist/core/types.d.ts.map +1 -1
  22. package/dist/core/types.js.map +1 -1
  23. package/dist/monitoring/GreenPrAutoMerger.d.ts +188 -0
  24. package/dist/monitoring/GreenPrAutoMerger.d.ts.map +1 -0
  25. package/dist/monitoring/GreenPrAutoMerger.js +393 -0
  26. package/dist/monitoring/GreenPrAutoMerger.js.map +1 -0
  27. package/dist/monitoring/GuardLatchStore.d.ts +134 -0
  28. package/dist/monitoring/GuardLatchStore.d.ts.map +1 -0
  29. package/dist/monitoring/GuardLatchStore.js +255 -0
  30. package/dist/monitoring/GuardLatchStore.js.map +1 -0
  31. package/dist/monitoring/MergeRunner.d.ts +126 -0
  32. package/dist/monitoring/MergeRunner.d.ts.map +1 -0
  33. package/dist/monitoring/MergeRunner.js +296 -0
  34. package/dist/monitoring/MergeRunner.js.map +1 -0
  35. package/dist/monitoring/floorDriftCanary.d.ts +88 -0
  36. package/dist/monitoring/floorDriftCanary.d.ts.map +1 -0
  37. package/dist/monitoring/floorDriftCanary.js +89 -0
  38. package/dist/monitoring/floorDriftCanary.js.map +1 -0
  39. package/dist/monitoring/greenPrAutomergeWiring.d.ts +73 -0
  40. package/dist/monitoring/greenPrAutomergeWiring.d.ts.map +1 -0
  41. package/dist/monitoring/greenPrAutomergeWiring.js +273 -0
  42. package/dist/monitoring/greenPrAutomergeWiring.js.map +1 -0
  43. package/dist/monitoring/greenPrLogic.d.ts +121 -0
  44. package/dist/monitoring/greenPrLogic.d.ts.map +1 -0
  45. package/dist/monitoring/greenPrLogic.js +198 -0
  46. package/dist/monitoring/greenPrLogic.js.map +1 -0
  47. package/dist/monitoring/guardManifest.d.ts.map +1 -1
  48. package/dist/monitoring/guardManifest.js +12 -0
  49. package/dist/monitoring/guardManifest.js.map +1 -1
  50. package/dist/server/AgentServer.d.ts +2 -0
  51. package/dist/server/AgentServer.d.ts.map +1 -1
  52. package/dist/server/AgentServer.js +2 -0
  53. package/dist/server/AgentServer.js.map +1 -1
  54. package/dist/server/CapabilityIndex.d.ts.map +1 -1
  55. package/dist/server/CapabilityIndex.js +16 -0
  56. package/dist/server/CapabilityIndex.js.map +1 -1
  57. package/dist/server/routes.d.ts +5 -0
  58. package/dist/server/routes.d.ts.map +1 -1
  59. package/dist/server/routes.js +112 -1
  60. package/dist/server/routes.js.map +1 -1
  61. package/dist/server/stopGate.d.ts +45 -0
  62. package/dist/server/stopGate.d.ts.map +1 -1
  63. package/dist/server/stopGate.js +74 -0
  64. package/dist/server/stopGate.js.map +1 -1
  65. package/package.json +1 -1
  66. package/scripts/safe-merge.mjs +449 -59
  67. package/src/data/builtin-manifest.json +64 -64
  68. package/upgrades/1.3.512.md +65 -0
  69. package/upgrades/side-effects/green-pr-automerge-enforcement.md +171 -0
@@ -0,0 +1,273 @@
1
+ /**
2
+ * greenPrAutomergeWiring — builds the real gh / fs / lease / latch dependencies
3
+ * for the GreenPrAutoMerger (green-pr-automerge-enforcement). Extracted from
4
+ * server.ts so the dependency construction is itself unit-testable (Testing
5
+ * Integrity: wiring-integrity tests prove deps are real, not nulls/no-ops).
6
+ *
7
+ * Repo-gated: the watcher only runs in the dev/maintainer environment where an
8
+ * analyzable instar git repo AND scripts/safe-merge.mjs are present. On a plain
9
+ * npm install both are absent → the server constructs nothing → routes 503.
10
+ *
11
+ * All gh goes through `execFile` (no shell). The list query is pinned oldest-first
12
+ * server-side. Identity (R4) is `gh api user`. Audit is one JSONL line per
13
+ * transition. State is per-machine (machine-local BY DESIGN).
14
+ *
15
+ * RULE 3.1 RATIONALE
16
+ * Criticality: high — these adapters surface the PR/identity/protected-paths
17
+ * state the merge watcher acts on.
18
+ * Frequency: per-tick (≤ once per ~10-minute interval).
19
+ * Stability: stable — every read uses `gh ... --json`/`gh api --jq`
20
+ * STRUCTURED output, never regex over human gh text.
21
+ * Fallback: a failing/unparseable list call THROWS (→ the watcher's
22
+ * tick-failed canary feeds the breaker); protectedPaths failure →
23
+ * `unverifiable:true` (→ skip, never merge); identity unresolved →
24
+ * skip. Every path fails toward NOT merging.
25
+ * Verdict: deterministic; safe-merge re-verifies at act time, so a misread
26
+ * here can only cause a refusal, never an unintended merge.
27
+ */
28
+ import fs from 'node:fs';
29
+ import path from 'node:path';
30
+ import { execFile } from 'node:child_process';
31
+ import { GuardLatchStore } from './GuardLatchStore.js';
32
+ import { DefaultMergeRunner } from './MergeRunner.js';
33
+ import { freshState, } from './GreenPrAutoMerger.js';
34
+ /** Protected globs (round-4/6): a PR touching these never auto-merges. */
35
+ export const PROTECTED_PATH_PREFIXES = [
36
+ '.github/',
37
+ 'scripts/safe-merge.mjs',
38
+ 'src/monitoring/GreenPrAutoMerger.ts',
39
+ 'src/monitoring/MergeRunner.ts',
40
+ 'src/monitoring/GuardLatchStore.ts',
41
+ 'src/monitoring/greenPrLogic.ts',
42
+ 'src/monitoring/floorDriftCanary.ts',
43
+ 'src/monitoring/greenPrAutomergeWiring.ts',
44
+ ];
45
+ /** Gate scripts the floor contexts execute (extend, never shrink). */
46
+ export const PROTECTED_GATE_SCRIPTS = [
47
+ 'scripts/safe-merge.mjs',
48
+ ];
49
+ export function isAnalyzableGreenPrRepo(repoPath, safeMergePath) {
50
+ try {
51
+ return fs.existsSync(path.join(repoPath, '.git')) && fs.existsSync(safeMergePath);
52
+ }
53
+ catch { /* @silent-fallback-ok: green-pr-automerge fail-safe — skip/refuse, never over-merge; safe-merge is the act-time authority */
54
+ return false;
55
+ }
56
+ }
57
+ /** Does any changed file touch a protected path? */
58
+ export function diffTouchesProtected(files) {
59
+ return files.some((f) => PROTECTED_PATH_PREFIXES.some((p) => f === p || f.startsWith(p)));
60
+ }
61
+ function gh(args) {
62
+ return new Promise((resolve) => {
63
+ execFile('gh', args, { maxBuffer: 16 * 1024 * 1024 }, (err, stdout, stderr) => {
64
+ resolve({ stdout: stdout ?? '', stderr: stderr ?? '', code: err ? err.code ?? 1 : 0 });
65
+ });
66
+ });
67
+ }
68
+ /** Build the GuardLatchStore for this install. */
69
+ export function buildGuardLatchStore(opts) {
70
+ return new GuardLatchStore({
71
+ stateDir: opts.stateDir,
72
+ machineId: opts.machineId,
73
+ journal: opts.journal,
74
+ leaseEpoch: opts.leaseEpoch,
75
+ readPeerEntries: opts.readPeerLatches,
76
+ now: opts.now ? () => new Date(opts.now()) : undefined,
77
+ logger: opts.logger,
78
+ });
79
+ }
80
+ /** Build the full GreenPrAutoMerger deps (real gh adapters). */
81
+ export function buildGreenPrDeps(opts, latches) {
82
+ const exec = opts.ghExec ?? gh;
83
+ const now = opts.now ?? (() => Date.now());
84
+ const runner = new DefaultMergeRunner({
85
+ stateDir: opts.stateDir,
86
+ repo: opts.repo,
87
+ safeMergePath: opts.safeMergePath,
88
+ mergeTimeoutMs: opts.mergeTimeoutMs,
89
+ mergeKillGraceMs: opts.mergeKillGraceMs,
90
+ expectedContractVersion: 2,
91
+ }, {
92
+ confirmMerged: async (pr, repo) => {
93
+ const r = await exec(['pr', 'view', String(pr), '--repo', repo, '--json', 'state,mergedAt']);
94
+ if (r.code !== 0)
95
+ return false;
96
+ try {
97
+ const j = JSON.parse(r.stdout);
98
+ return j.state === 'MERGED' || !!j.mergedAt;
99
+ }
100
+ catch { /* @silent-fallback-ok: green-pr-automerge fail-safe — skip/refuse, never over-merge; safe-merge is the act-time authority */
101
+ return false;
102
+ }
103
+ },
104
+ prState: async (pr, repo) => {
105
+ const r = await exec(['pr', 'view', String(pr), '--repo', repo, '--json', 'state']);
106
+ if (r.code !== 0)
107
+ return 'UNKNOWN';
108
+ try {
109
+ return String(JSON.parse(r.stdout).state ?? 'UNKNOWN');
110
+ }
111
+ catch { /* @silent-fallback-ok: green-pr-automerge fail-safe — skip/refuse, never over-merge; safe-merge is the act-time authority */
112
+ return 'UNKNOWN';
113
+ }
114
+ },
115
+ logger: opts.logger,
116
+ });
117
+ const audit = (event) => {
118
+ try {
119
+ const dir = path.dirname(opts.auditPath);
120
+ if (!fs.existsSync(dir))
121
+ fs.mkdirSync(dir, { recursive: true });
122
+ fs.appendFileSync(opts.auditPath, JSON.stringify({ ts: new Date(now()).toISOString(), ...event }) + '\n', { mode: 0o600 });
123
+ }
124
+ catch { /* @silent-fallback-ok: green-pr-automerge fail-safe — skip/refuse, never over-merge; safe-merge is the act-time authority */ /* audit failure is non-fatal */ }
125
+ };
126
+ const statePath = path.join(opts.stateDir, 'state', 'green-pr-automerge.json');
127
+ const loadState = () => {
128
+ try {
129
+ const raw = fs.readFileSync(statePath, 'utf-8');
130
+ const obj = JSON.parse(raw);
131
+ return { ...freshState(), ...obj };
132
+ }
133
+ catch { /* @silent-fallback-ok: green-pr-automerge fail-safe — skip/refuse, never over-merge; safe-merge is the act-time authority */
134
+ return freshState();
135
+ }
136
+ };
137
+ const saveState = (state) => {
138
+ try {
139
+ const dir = path.dirname(statePath);
140
+ if (!fs.existsSync(dir))
141
+ fs.mkdirSync(dir, { recursive: true });
142
+ const tmp = statePath + '.tmp';
143
+ fs.writeFileSync(tmp, JSON.stringify(state), { mode: 0o600 });
144
+ fs.renameSync(tmp, statePath);
145
+ }
146
+ catch { /* @silent-fallback-ok: green-pr-automerge fail-safe — skip/refuse, never over-merge; safe-merge is the act-time authority */ /* best-effort */ }
147
+ };
148
+ return {
149
+ holdsLease: opts.holdsLease,
150
+ leaseEpoch: opts.leaseEpoch,
151
+ listOpenPrs: async () => {
152
+ const r = await exec([
153
+ 'pr', 'list', '--author', '@me', '--state', 'open', '--base', 'main',
154
+ '--limit', '100', '--json', 'number,title,labels,isDraft,headRefName,headRefOid,mergeable,statusCheckRollup',
155
+ '--search', 'sort:created-asc',
156
+ ]);
157
+ if (r.code !== 0)
158
+ throw new Error(`gh pr list failed: ${r.stderr.slice(0, 200)}`);
159
+ const rows = JSON.parse(r.stdout);
160
+ return rows.map(mapPr);
161
+ },
162
+ protectedPaths: async (pr) => {
163
+ // Enumerate changed files to exhaustion via the API (paginated).
164
+ const r = await exec(['api', `repos/${opts.repo}/pulls/${pr.number}/files`, '--paginate', '--jq', '.[].filename']);
165
+ if (r.code !== 0)
166
+ return { touches: false, unverifiable: true };
167
+ const files = r.stdout.split('\n').map((s) => s.trim()).filter(Boolean);
168
+ return { touches: diffTouchesProtected(files), unverifiable: false };
169
+ },
170
+ refetchPr: async (pr) => {
171
+ const r = await exec(['pr', 'view', String(pr), '--repo', opts.repo, '--json', 'title,labels,isDraft,headRefOid,state']);
172
+ if (r.code !== 0)
173
+ return null;
174
+ try {
175
+ const j = JSON.parse(r.stdout);
176
+ return {
177
+ title: String(j.title ?? ''),
178
+ labels: Array.isArray(j.labels) ? j.labels.map((l) => l.name ?? '') : [],
179
+ isDraft: !!j.isDraft,
180
+ headRefOid: String(j.headRefOid ?? ''),
181
+ state: String(j.state ?? 'UNKNOWN'),
182
+ };
183
+ }
184
+ catch { /* @silent-fallback-ok: green-pr-automerge fail-safe — skip/refuse, never over-merge; safe-merge is the act-time authority */
185
+ return null;
186
+ }
187
+ },
188
+ resolveGhLogin: async () => {
189
+ const r = await exec(['api', 'user', '--jq', '.login']);
190
+ if (r.code !== 0)
191
+ return null;
192
+ const login = r.stdout.trim();
193
+ return login || null;
194
+ },
195
+ holdEligible: async (pr) => {
196
+ const r = await exec(['pr', 'view', String(pr), '--repo', opts.repo, '--json', 'state,headRefName']);
197
+ if (r.code !== 0)
198
+ return { ok: false, status: 404, detail: 'PR not found' };
199
+ try {
200
+ const j = JSON.parse(r.stdout);
201
+ if (j.state !== 'OPEN')
202
+ return { ok: false, status: 409, detail: `PR is ${j.state}` };
203
+ const ns = opts.agentNamespace.endsWith('/') ? opts.agentNamespace : `${opts.agentNamespace}/`;
204
+ if (!String(j.headRefName ?? '').startsWith(ns))
205
+ return { ok: false, status: 403, detail: 'PR is not in this agent\'s namespace' };
206
+ return { ok: true };
207
+ }
208
+ catch { /* @silent-fallback-ok: green-pr-automerge fail-safe — skip/refuse, never over-merge; safe-merge is the act-time authority */
209
+ return { ok: false, status: 502, detail: 'unparseable gh response' };
210
+ }
211
+ },
212
+ applyHoldMarker: async (pr, reason) => {
213
+ // Read the current title, prefix [HOLD: …] (idempotent if already held).
214
+ const view = await exec(['pr', 'view', String(pr), '--repo', opts.repo, '--json', 'title']);
215
+ if (view.code !== 0)
216
+ return false;
217
+ let title = '';
218
+ try {
219
+ title = String(JSON.parse(view.stdout).title ?? '');
220
+ }
221
+ catch { /* @silent-fallback-ok: green-pr-automerge fail-safe — skip/refuse, never over-merge; safe-merge is the act-time authority */
222
+ return false;
223
+ }
224
+ if (title.trim().toLowerCase().startsWith('[hold'))
225
+ return true; // already held
226
+ const safeReason = reason.replace(/[\]\n\r]/g, ' ').slice(0, 80);
227
+ const newTitle = `[HOLD: ${safeReason || 'held'}] ${title}`.slice(0, 256);
228
+ const edit = await exec(['pr', 'edit', String(pr), '--repo', opts.repo, '--title', newTitle]);
229
+ return edit.code === 0;
230
+ },
231
+ runner,
232
+ latches,
233
+ postAttentionAggregate: opts.postAttentionAggregate,
234
+ audit,
235
+ loadState,
236
+ saveState,
237
+ now,
238
+ };
239
+ }
240
+ function mapPr(row) {
241
+ const labels = Array.isArray(row.labels) ? row.labels.map((l) => l.name ?? '') : [];
242
+ const rollup = row.statusCheckRollup;
243
+ return {
244
+ number: Number(row.number),
245
+ title: String(row.title ?? ''),
246
+ labels,
247
+ isDraft: !!row.isDraft,
248
+ headRefName: String(row.headRefName ?? ''),
249
+ headRefOid: String(row.headRefOid ?? ''),
250
+ mergeable: String(row.mergeable ?? 'UNKNOWN'),
251
+ statusRollup: deriveRollup(rollup),
252
+ };
253
+ }
254
+ /** Derive a single SUCCESS|PENDING|FAILURE from the statusCheckRollup array. */
255
+ export function deriveRollup(rollup) {
256
+ if (!Array.isArray(rollup))
257
+ return typeof rollup === 'string' ? rollup : null;
258
+ let sawPending = false;
259
+ for (const c of rollup) {
260
+ const state = String(c.state ?? c.conclusion ?? '').toUpperCase();
261
+ const status = String(c.status ?? '').toUpperCase();
262
+ if (status && status !== 'COMPLETED') {
263
+ sawPending = true;
264
+ continue;
265
+ }
266
+ if (state === 'FAILURE' || state === 'ERROR' || state === 'CANCELLED' || state === 'TIMED_OUT')
267
+ return 'FAILURE';
268
+ if (state === 'PENDING' || state === 'EXPECTED' || state === 'IN_PROGRESS' || state === 'QUEUED')
269
+ sawPending = true;
270
+ }
271
+ return sawPending ? 'PENDING' : 'SUCCESS';
272
+ }
273
+ //# sourceMappingURL=greenPrAutomergeWiring.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"greenPrAutomergeWiring.js","sourceRoot":"","sources":["../../src/monitoring/greenPrAutomergeWiring.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,121 @@
1
+ /**
2
+ * greenPrLogic — PURE decision helpers for the GreenPrAutoMerger
3
+ * (green-pr-automerge-enforcement). No I/O, no clock of their own (time is
4
+ * passed in), so every decision boundary is unit-testable on both sides.
5
+ *
6
+ * The orchestrating class (GreenPrAutoMerger.ts) wires these to real gh /
7
+ * safe-merge / lease / latch / audit I/O.
8
+ */
9
+ /** One PR as returned by the `gh pr list` GraphQL projection. */
10
+ export interface PrSummary {
11
+ number: number;
12
+ title: string;
13
+ labels: string[];
14
+ isDraft: boolean;
15
+ headRefName: string;
16
+ headRefOid: string;
17
+ /** GraphQL mergeable enum: MERGEABLE | CONFLICTING | UNKNOWN. */
18
+ mergeable: string;
19
+ /** Worst-case rollup of the head's checks: SUCCESS | PENDING | FAILURE | null. */
20
+ statusRollup: string | null;
21
+ }
22
+ export type HoldReason = 'draft' | 'hold-title' | 'hold-label' | null;
23
+ /** A PR is held (excluded) by a deliberate marker. Returns WHY, or null. */
24
+ export declare function holdReasonOf(pr: Pick<PrSummary, 'isDraft' | 'title' | 'labels'>): HoldReason;
25
+ export type CandidateSkip = 'not-agent-namespace' | 'held' | 'not-mergeable' | 'not-settled-green' | 'protected-paths' | 'protected-paths-unverifiable';
26
+ export interface CandidateVerdict {
27
+ eligible: boolean;
28
+ skip?: CandidateSkip;
29
+ hold?: HoldReason;
30
+ }
31
+ /**
32
+ * First-pass candidacy from the list projection alone (cheap fields). Protected
33
+ * paths require a separate diff enumeration (handled by the caller and folded in
34
+ * via `protectedPaths`), so this returns `eligible:true` only when the cheap
35
+ * gates ALL pass; the caller still runs the protected-paths check before acting.
36
+ */
37
+ export declare function classifyCandidate(pr: PrSummary, agentNamespace: string): CandidateVerdict;
38
+ /** A head branch `<agentName>/...` filter (a FILTER, not provenance — Decision 8). */
39
+ export declare function headInNamespace(headRefName: string, agentNamespace: string): boolean;
40
+ /**
41
+ * Oldest-first selection over the FULL fetched set (the list query is pinned
42
+ * oldest-first server-side; this is the deterministic tiebreak by PR number).
43
+ */
44
+ export declare function selectOldest(candidates: PrSummary[]): PrSummary | null;
45
+ export interface HoldMemoryEntry {
46
+ /** Consecutive ticks (same lease holder) the marker has been ABSENT. */
47
+ absentTicks: number;
48
+ /** ms timestamp the PR was first observed held this episode. */
49
+ firstHeldAt: number;
50
+ /** ms timestamp of the most recent absence observation. */
51
+ lastAbsentAt?: number;
52
+ }
53
+ /**
54
+ * Update hold memory for a PR and decide whether it is eligible to RESUME.
55
+ * A PR observed held resumes only after the marker is absent for
56
+ * `holdReleaseTicks` consecutive ticks AND `>= tickIntervalMs` elapsed
57
+ * (tick-AND-time so a manual double-tick cannot collapse the window).
58
+ */
59
+ export declare function debounceHoldRelease(mem: HoldMemoryEntry | undefined, currentlyHeld: boolean, nowMs: number, holdReleaseTicks: number, tickIntervalMs: number): {
60
+ mem: HoldMemoryEntry | undefined;
61
+ resumeEligible: boolean;
62
+ transition: 'still-held' | 'released' | 'observing-release' | 'not-held';
63
+ };
64
+ export interface Episode {
65
+ pr: number;
66
+ headRefOid: string;
67
+ attempts: number;
68
+ rearmEpisodes: number;
69
+ state: 'active' | 'gave-up';
70
+ lastAttemptAt?: number;
71
+ nextEligibleAt?: number;
72
+ lastOutcome?: string;
73
+ }
74
+ export interface LadderConfig {
75
+ maxAttempts: number;
76
+ maxRearmEpisodes: number;
77
+ backoffBaseMs: number;
78
+ }
79
+ /**
80
+ * Fold a merge OUTCOME into the PR's episode. Returns the updated episode and
81
+ * whether this counts as a breaker-feeding failure. `already-merged` /
82
+ * `closed` are success-noops (never ladder failures). A `refused`/`error`
83
+ * advances the attempt ladder with backoff; at `maxAttempts` the episode is
84
+ * `gave-up` (re-armable by a NEW head sha up to `maxRearmEpisodes`).
85
+ */
86
+ export declare function applyOutcome(ep: Episode, outcome: string, nowMs: number, cfg: LadderConfig): {
87
+ ep: Episode;
88
+ terminal: boolean;
89
+ feedsBreaker: boolean;
90
+ };
91
+ /**
92
+ * Re-arm a gave-up episode when a NEW head sha appears (the author pushed a
93
+ * fix). Bounded by `maxRearmEpisodes` — beyond that, manual action is required.
94
+ */
95
+ export declare function maybeRearm(ep: Episode, newHeadOid: string, cfg: LadderConfig): Episode | null;
96
+ /** Is the episode currently eligible to attempt (active + backoff elapsed)? */
97
+ export declare function episodeEligible(ep: Episode | undefined, nowMs: number): boolean;
98
+ export interface BreakerState {
99
+ open: boolean;
100
+ openedAt?: number;
101
+ consecutiveBusySkips: number;
102
+ consecutiveDeadlineKills: number;
103
+ consecutiveTickFailures: number;
104
+ }
105
+ export interface BreakerConfig {
106
+ busySkipBreakerThreshold: number;
107
+ deadlineKillBreakerThreshold: number;
108
+ breakerThreshold: number;
109
+ breakerCooldownMs: number;
110
+ }
111
+ export declare function freshBreaker(): BreakerState;
112
+ /** Is the breaker open AND still within its cooldown? */
113
+ export declare function breakerBlocking(b: BreakerState, nowMs: number, cooldownMs: number): boolean;
114
+ /** Fold a breaker SIGNAL; returns the updated state (may open the breaker). */
115
+ export declare function feedBreaker(b: BreakerState, signal: 'busy-skip' | 'deadline-kill' | 'tick-failed' | 'reset', nowMs: number, cfg: BreakerConfig): BreakerState;
116
+ /** Boot-time invariant (B24): busy-skip budget must outlast a single merge. */
117
+ export declare function validateTimeoutInvariant(busySkipBreakerThreshold: number, tickIntervalMs: number, mergeTimeoutMs: number, mergeKillGraceMs: number): {
118
+ ok: boolean;
119
+ reason?: string;
120
+ };
121
+ //# sourceMappingURL=greenPrLogic.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"greenPrLogic.d.ts","sourceRoot":"","sources":["../../src/monitoring/greenPrLogic.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,198 @@
1
+ /**
2
+ * greenPrLogic — PURE decision helpers for the GreenPrAutoMerger
3
+ * (green-pr-automerge-enforcement). No I/O, no clock of their own (time is
4
+ * passed in), so every decision boundary is unit-testable on both sides.
5
+ *
6
+ * The orchestrating class (GreenPrAutoMerger.ts) wires these to real gh /
7
+ * safe-merge / lease / latch / audit I/O.
8
+ */
9
+ /** A PR is held (excluded) by a deliberate marker. Returns WHY, or null. */
10
+ export function holdReasonOf(pr) {
11
+ if (pr.isDraft)
12
+ return 'draft';
13
+ // Title trimmed before the prefix match (round-5: a hand-edited " [HOLD]" with
14
+ // leading whitespace must not silently fail).
15
+ const title = (pr.title ?? '').trim().toLowerCase();
16
+ if (title.startsWith('[hold'))
17
+ return 'hold-title';
18
+ const labels = (pr.labels ?? []).map((l) => l.toLowerCase());
19
+ if (labels.includes('hold') || labels.includes('do-not-merge'))
20
+ return 'hold-label';
21
+ return null;
22
+ }
23
+ /**
24
+ * First-pass candidacy from the list projection alone (cheap fields). Protected
25
+ * paths require a separate diff enumeration (handled by the caller and folded in
26
+ * via `protectedPaths`), so this returns `eligible:true` only when the cheap
27
+ * gates ALL pass; the caller still runs the protected-paths check before acting.
28
+ */
29
+ export function classifyCandidate(pr, agentNamespace) {
30
+ if (!headInNamespace(pr.headRefName, agentNamespace)) {
31
+ return { eligible: false, skip: 'not-agent-namespace' };
32
+ }
33
+ const hold = holdReasonOf(pr);
34
+ if (hold)
35
+ return { eligible: false, skip: 'held', hold };
36
+ if (pr.mergeable !== 'MERGEABLE')
37
+ return { eligible: false, skip: 'not-mergeable' };
38
+ // "Settled green" — the watcher NEVER invokes safe-merge into a pending wait
39
+ // (keeps each attempt window seconds-long; timeout inversion impossible).
40
+ if (pr.statusRollup !== 'SUCCESS')
41
+ return { eligible: false, skip: 'not-settled-green' };
42
+ return { eligible: true };
43
+ }
44
+ /** A head branch `<agentName>/...` filter (a FILTER, not provenance — Decision 8). */
45
+ export function headInNamespace(headRefName, agentNamespace) {
46
+ if (!agentNamespace)
47
+ return false;
48
+ const prefix = agentNamespace.endsWith('/') ? agentNamespace : `${agentNamespace}/`;
49
+ return headRefName.startsWith(prefix);
50
+ }
51
+ /**
52
+ * Oldest-first selection over the FULL fetched set (the list query is pinned
53
+ * oldest-first server-side; this is the deterministic tiebreak by PR number).
54
+ */
55
+ export function selectOldest(candidates) {
56
+ if (candidates.length === 0)
57
+ return null;
58
+ return [...candidates].sort((a, b) => a.number - b.number)[0];
59
+ }
60
+ /**
61
+ * Update hold memory for a PR and decide whether it is eligible to RESUME.
62
+ * A PR observed held resumes only after the marker is absent for
63
+ * `holdReleaseTicks` consecutive ticks AND `>= tickIntervalMs` elapsed
64
+ * (tick-AND-time so a manual double-tick cannot collapse the window).
65
+ */
66
+ export function debounceHoldRelease(mem, currentlyHeld, nowMs, holdReleaseTicks, tickIntervalMs) {
67
+ if (currentlyHeld) {
68
+ return {
69
+ mem: { absentTicks: 0, firstHeldAt: mem?.firstHeldAt ?? nowMs },
70
+ resumeEligible: false,
71
+ transition: 'still-held',
72
+ };
73
+ }
74
+ // Not held right now.
75
+ if (!mem) {
76
+ // Never seen held → no debounce needed.
77
+ return { mem: undefined, resumeEligible: true, transition: 'not-held' };
78
+ }
79
+ const absentTicks = mem.absentTicks + 1;
80
+ const elapsedOk = (nowMs - (mem.firstHeldAt ?? nowMs)) >= tickIntervalMs;
81
+ if (absentTicks >= holdReleaseTicks && elapsedOk) {
82
+ return { mem: undefined, resumeEligible: true, transition: 'released' };
83
+ }
84
+ return {
85
+ mem: { absentTicks, firstHeldAt: mem.firstHeldAt, lastAbsentAt: nowMs },
86
+ resumeEligible: false,
87
+ transition: 'observing-release',
88
+ };
89
+ }
90
+ /**
91
+ * Fold a merge OUTCOME into the PR's episode. Returns the updated episode and
92
+ * whether this counts as a breaker-feeding failure. `already-merged` /
93
+ * `closed` are success-noops (never ladder failures). A `refused`/`error`
94
+ * advances the attempt ladder with backoff; at `maxAttempts` the episode is
95
+ * `gave-up` (re-armable by a NEW head sha up to `maxRearmEpisodes`).
96
+ */
97
+ export function applyOutcome(ep, outcome, nowMs, cfg) {
98
+ const next = { ...ep };
99
+ if (outcome === 'merged') {
100
+ next.state = 'gave-up'; // episode complete; reaped by the caller on confirm
101
+ next.lastOutcome = 'merged';
102
+ return { ep: next, terminal: true, feedsBreaker: false };
103
+ }
104
+ if (outcome === 'already-merged' || outcome === 'closed' || outcome === 'merged-by-other' || outcome === 'closed-by-other') {
105
+ next.lastOutcome = outcome;
106
+ next.state = 'gave-up';
107
+ return { ep: next, terminal: true, feedsBreaker: false };
108
+ }
109
+ // A real refusal/error: advance the ladder.
110
+ next.attempts = ep.attempts + 1;
111
+ next.lastAttemptAt = nowMs;
112
+ next.lastOutcome = outcome;
113
+ const backoff = cfg.backoffBaseMs * Math.pow(2, Math.min(next.attempts - 1, 6));
114
+ next.nextEligibleAt = nowMs + backoff;
115
+ if (next.attempts >= cfg.maxAttempts) {
116
+ next.state = 'gave-up';
117
+ }
118
+ return { ep: next, terminal: next.state === 'gave-up', feedsBreaker: true };
119
+ }
120
+ /**
121
+ * Re-arm a gave-up episode when a NEW head sha appears (the author pushed a
122
+ * fix). Bounded by `maxRearmEpisodes` — beyond that, manual action is required.
123
+ */
124
+ export function maybeRearm(ep, newHeadOid, cfg) {
125
+ if (ep.state !== 'gave-up')
126
+ return ep;
127
+ if (ep.headRefOid === newHeadOid)
128
+ return ep; // same head, still given up
129
+ if (ep.rearmEpisodes >= cfg.maxRearmEpisodes)
130
+ return null; // exhausted
131
+ return {
132
+ pr: ep.pr,
133
+ headRefOid: newHeadOid,
134
+ attempts: 0,
135
+ rearmEpisodes: ep.rearmEpisodes + 1,
136
+ state: 'active',
137
+ };
138
+ }
139
+ /** Is the episode currently eligible to attempt (active + backoff elapsed)? */
140
+ export function episodeEligible(ep, nowMs) {
141
+ if (!ep)
142
+ return true; // first attempt
143
+ if (ep.state === 'gave-up')
144
+ return false;
145
+ if (ep.nextEligibleAt && nowMs < ep.nextEligibleAt)
146
+ return false;
147
+ return true;
148
+ }
149
+ export function freshBreaker() {
150
+ return { open: false, consecutiveBusySkips: 0, consecutiveDeadlineKills: 0, consecutiveTickFailures: 0 };
151
+ }
152
+ /** Is the breaker open AND still within its cooldown? */
153
+ export function breakerBlocking(b, nowMs, cooldownMs) {
154
+ if (!b.open)
155
+ return false;
156
+ if (b.openedAt && nowMs - b.openedAt >= cooldownMs)
157
+ return false; // cooled down
158
+ return true;
159
+ }
160
+ /** Fold a breaker SIGNAL; returns the updated state (may open the breaker). */
161
+ export function feedBreaker(b, signal, nowMs, cfg) {
162
+ const next = { ...b };
163
+ if (signal === 'reset') {
164
+ return { ...next, consecutiveBusySkips: 0, consecutiveDeadlineKills: 0, consecutiveTickFailures: 0, open: false, openedAt: undefined };
165
+ }
166
+ if (signal === 'busy-skip') {
167
+ next.consecutiveBusySkips += 1;
168
+ if (next.consecutiveBusySkips >= cfg.busySkipBreakerThreshold) {
169
+ next.open = true;
170
+ next.openedAt = nowMs;
171
+ }
172
+ }
173
+ else if (signal === 'deadline-kill') {
174
+ next.consecutiveDeadlineKills += 1;
175
+ if (next.consecutiveDeadlineKills >= cfg.deadlineKillBreakerThreshold) {
176
+ next.open = true;
177
+ next.openedAt = nowMs;
178
+ }
179
+ }
180
+ else if (signal === 'tick-failed') {
181
+ next.consecutiveTickFailures += 1;
182
+ if (next.consecutiveTickFailures >= cfg.breakerThreshold) {
183
+ next.open = true;
184
+ next.openedAt = nowMs;
185
+ }
186
+ }
187
+ return next;
188
+ }
189
+ /** Boot-time invariant (B24): busy-skip budget must outlast a single merge. */
190
+ export function validateTimeoutInvariant(busySkipBreakerThreshold, tickIntervalMs, mergeTimeoutMs, mergeKillGraceMs) {
191
+ const budget = busySkipBreakerThreshold * tickIntervalMs;
192
+ const need = mergeTimeoutMs + mergeKillGraceMs;
193
+ if (budget <= need) {
194
+ return { ok: false, reason: `busySkipBreakerThreshold(${busySkipBreakerThreshold}) × tickIntervalMs(${tickIntervalMs}) = ${budget} must exceed mergeTimeoutMs(${mergeTimeoutMs}) + mergeKillGraceMs(${mergeKillGraceMs}) = ${need}` };
195
+ }
196
+ return { ok: true };
197
+ }
198
+ //# sourceMappingURL=greenPrLogic.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"greenPrLogic.js","sourceRoot":"","sources":["../../src/monitoring/greenPrLogic.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"guardManifest.d.ts","sourceRoot":"","sources":["../../src/monitoring/guardManifest.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAEH,MAAM,MAAM,SAAS,GAAG,QAAQ,GAAG,cAAc,CAAC;AAClD,MAAM,MAAM,YAAY,GAAG,QAAQ,GAAG,UAAU,CAAC;AAEjD,MAAM,WAAW,kBAAkB;IACjC,6FAA6F;IAC7F,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,SAAS,CAAC;IAChB,6EAA6E;IAC7E,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB;;qFAEiF;IACjF,cAAc,EAAE,OAAO,CAAC;IACxB,6DAA6D;IAC7D,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,8EAA8E;IAC9E,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB;wEACoE;IACpE,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,OAAO,EAAE,YAAY,CAAC;IACtB;;;;2DAIuD;IACvD,aAAa,EAAE,OAAO,CAAC;IACvB,wEAAwE;IACxE,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,eAAO,MAAM,cAAc,EAAE,SAAS,kBAAkB,EA8b9C,CAAC;AAEX;;;;;;GAMG;AACH,MAAM,WAAW,cAAc;IAC7B,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,eAAO,MAAM,WAAW,EAAE,SAAS,cAAc,EA8EvC,CAAC;AAEX,qFAAqF;AACrF,wBAAgB,aAAa,IAAI,GAAG,CAAC,MAAM,EAAE,kBAAkB,CAAC,CAI/D;AAED,wBAAgB,kBAAkB,IAAI,GAAG,CAAC,MAAM,CAAC,CAIhD;AAED,wBAAgB,mBAAmB,IAAI,GAAG,CAAC,MAAM,CAAC,CAEjD"}
1
+ {"version":3,"file":"guardManifest.d.ts","sourceRoot":"","sources":["../../src/monitoring/guardManifest.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAEH,MAAM,MAAM,SAAS,GAAG,QAAQ,GAAG,cAAc,CAAC;AAClD,MAAM,MAAM,YAAY,GAAG,QAAQ,GAAG,UAAU,CAAC;AAEjD,MAAM,WAAW,kBAAkB;IACjC,6FAA6F;IAC7F,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,SAAS,CAAC;IAChB,6EAA6E;IAC7E,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB;;qFAEiF;IACjF,cAAc,EAAE,OAAO,CAAC;IACxB,6DAA6D;IAC7D,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,8EAA8E;IAC9E,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB;wEACoE;IACpE,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,OAAO,EAAE,YAAY,CAAC;IACtB;;;;2DAIuD;IACvD,aAAa,EAAE,OAAO,CAAC;IACvB,wEAAwE;IACxE,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,eAAO,MAAM,cAAc,EAAE,SAAS,kBAAkB,EA0c9C,CAAC;AAEX;;;;;;GAMG;AACH,MAAM,WAAW,cAAc;IAC7B,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,eAAO,MAAM,WAAW,EAAE,SAAS,cAAc,EA8EvC,CAAC;AAEX,qFAAqF;AACrF,wBAAgB,aAAa,IAAI,GAAG,CAAC,MAAM,EAAE,kBAAkB,CAAC,CAI/D;AAED,wBAAgB,kBAAkB,IAAI,GAAG,CAAC,MAAM,CAAC,CAIhD;AAED,wBAAgB,mBAAmB,IAAI,GAAG,CAAC,MAAM,CAAC,CAEjD"}