instar 1.3.599 → 1.3.601
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/dist/commands/server.d.ts.map +1 -1
- package/dist/commands/server.js +77 -3
- package/dist/commands/server.js.map +1 -1
- package/dist/core/BackupManager.d.ts.map +1 -1
- package/dist/core/BackupManager.js +5 -0
- package/dist/core/BackupManager.js.map +1 -1
- package/dist/core/PostUpdateMigrator.d.ts +1 -0
- package/dist/core/PostUpdateMigrator.d.ts.map +1 -1
- package/dist/core/PostUpdateMigrator.js +104 -0
- package/dist/core/PostUpdateMigrator.js.map +1 -1
- package/dist/core/PrHandLease.d.ts +151 -0
- package/dist/core/PrHandLease.d.ts.map +1 -0
- package/dist/core/PrHandLease.js +448 -0
- package/dist/core/PrHandLease.js.map +1 -0
- package/dist/core/devGatedFeatures.d.ts.map +1 -1
- package/dist/core/devGatedFeatures.js +12 -0
- package/dist/core/devGatedFeatures.js.map +1 -1
- package/dist/core/instarSettingsHooks.d.ts.map +1 -1
- package/dist/core/instarSettingsHooks.js +10 -0
- package/dist/core/instarSettingsHooks.js.map +1 -1
- package/dist/core/multiMachineCapstoneMatrix.d.ts +49 -0
- package/dist/core/multiMachineCapstoneMatrix.d.ts.map +1 -0
- package/dist/core/multiMachineCapstoneMatrix.js +131 -0
- package/dist/core/multiMachineCapstoneMatrix.js.map +1 -0
- package/dist/scaffold/templates.d.ts.map +1 -1
- package/dist/scaffold/templates.js +2 -0
- package/dist/scaffold/templates.js.map +1 -1
- package/dist/server/AgentServer.d.ts +36 -0
- package/dist/server/AgentServer.d.ts.map +1 -1
- package/dist/server/AgentServer.js +2 -0
- package/dist/server/AgentServer.js.map +1 -1
- package/dist/server/CapabilityIndex.d.ts.map +1 -1
- package/dist/server/CapabilityIndex.js +2 -0
- package/dist/server/CapabilityIndex.js.map +1 -1
- package/dist/server/routes.d.ts +7 -0
- package/dist/server/routes.d.ts.map +1 -1
- package/dist/server/routes.js +251 -0
- package/dist/server/routes.js.map +1 -1
- package/package.json +1 -1
- package/src/data/builtin-manifest.json +65 -65
- package/src/scaffold/templates.ts +2 -0
- package/upgrades/1.3.600.md +44 -0
- package/upgrades/1.3.601.md +38 -0
- package/upgrades/side-effects/live-test-capstone-runner-route.md +89 -0
- package/upgrades/side-effects/parallel-hand-pr-lease.md +153 -0
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* PrHandLease — per-branch ownership lease so two of the agent's OWN concurrent
|
|
3
|
+
* sessions ("hands") cannot push competing commits to the same branch.
|
|
4
|
+
*
|
|
5
|
+
* Spec: docs/specs/parallel-hand-pr-lease.md (review-convergence + approved).
|
|
6
|
+
* Closes the push-competition cause of the 2026-06-15 PR #1183 merge thrash.
|
|
7
|
+
*
|
|
8
|
+
* Design anchors (from the converged spec):
|
|
9
|
+
* - Identity = holderTopicId (stable across the constant session respawns);
|
|
10
|
+
* holderSessionId is a LIVENESS-PROBE HANDLE ONLY, never the identity (§3.2/B2).
|
|
11
|
+
* - ONE process-wide lock guards the single JSON file (matching ResumeQueue's
|
|
12
|
+
* single lockPath); per-record compare-and-swap under that lock (§3.3/B3/M-D).
|
|
13
|
+
* - Liveness probe is TTL-gated (only when a lease is past ttl) and reads the
|
|
14
|
+
* in-memory running set — never a tmux exec (§3.5/M4).
|
|
15
|
+
* - A holder on a DIFFERENT machine is NEVER judged dead from local session
|
|
16
|
+
* absence (§3.5/M6); foreign-machine holder → fail-closed → treat as live.
|
|
17
|
+
* - maxHold ceiling is liveness-discriminated: a DEAD/foreign-unverified holder
|
|
18
|
+
* past the ceiling is CAS-seized + attention; a LIVE same-machine holder past
|
|
19
|
+
* the ceiling is NOT seized — the caller escalates instead (§3.9/codex#3).
|
|
20
|
+
* - Unreadable/corrupt/absent state file → fail-OPEN (treat as no lease) (§3.4/M10).
|
|
21
|
+
* - dryRun leases carry dryRun:true; non-acquisition readers MUST ignore them (§5).
|
|
22
|
+
*
|
|
23
|
+
* This module is the STORE + the pure key-derivation helpers. The PreToolUse Bash
|
|
24
|
+
* hook (pr-hand-lease-guard.js) and the GET /pr-leases route consume it. Enforcement
|
|
25
|
+
* is the hook's (the real chokepoint where agent `git push` runs); SafeGitExecutor
|
|
26
|
+
* carries the same check as defense-in-depth for instar's own internal pushes.
|
|
27
|
+
*/
|
|
28
|
+
export type LeaseIntent = 'build' | 'rework' | 'merge';
|
|
29
|
+
export type LeaseTombstoneStatus = 'released' | 'merged' | 'abandoned';
|
|
30
|
+
export interface PrHandLeaseRecord {
|
|
31
|
+
/** STABLE logical owner — the conversation topic. Survives session respawn. */
|
|
32
|
+
holderTopicId: number;
|
|
33
|
+
/** Liveness-probe handle ONLY (tmux session name). NEVER the identity. */
|
|
34
|
+
holderSessionId: string;
|
|
35
|
+
/** Load-bearing for the never-falsely-dead rule (§3.5/M6). */
|
|
36
|
+
holderMachineId: string;
|
|
37
|
+
/** Secondary metadata once the PR exists; never the primary key. */
|
|
38
|
+
prNumber?: number | null;
|
|
39
|
+
intent: LeaseIntent;
|
|
40
|
+
acquiredAt: number;
|
|
41
|
+
renewedAt: number;
|
|
42
|
+
ttlMs: number;
|
|
43
|
+
maxHoldMs: number;
|
|
44
|
+
/** Observe-only soak: a dryRun lease MUST be ignored by all non-acquisition readers. */
|
|
45
|
+
dryRun?: boolean;
|
|
46
|
+
/** Set only on a tombstoned (released) record; a tombstone is never a live holder. */
|
|
47
|
+
tombstone?: {
|
|
48
|
+
status: LeaseTombstoneStatus;
|
|
49
|
+
at: number;
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
/** Derived liveness reported by GET /pr-leases — honest, computed, never the raw record. */
|
|
53
|
+
export type DerivedLeaseLiveness = 'live' | 'stale-dead' | 'stale-ttl' | 'tombstoned' | 'foreign-machine';
|
|
54
|
+
export interface LeaseEvalResult {
|
|
55
|
+
/** What the push chokepoint should do. */
|
|
56
|
+
decision: 'allow' | 'deny' | 'escalate';
|
|
57
|
+
reason: string;
|
|
58
|
+
holder?: PrHandLeaseRecord;
|
|
59
|
+
}
|
|
60
|
+
export interface PrHandLeaseDeps {
|
|
61
|
+
stateDir: string;
|
|
62
|
+
machineId: string;
|
|
63
|
+
/** Returns the tmux session names currently running (in-memory; no tmux exec). */
|
|
64
|
+
runningSessionNames: () => string[];
|
|
65
|
+
/** ms clock (injectable for tests). */
|
|
66
|
+
now?: () => number;
|
|
67
|
+
/** Emitted on a forced release / fail-open recurrence for the attention surface. */
|
|
68
|
+
onAttention?: (item: {
|
|
69
|
+
kind: string;
|
|
70
|
+
detail: string;
|
|
71
|
+
}) => void;
|
|
72
|
+
/** Structured audit sink — one row per acquire/renew/yield/auto-heal/release. */
|
|
73
|
+
onAudit?: (row: Record<string, unknown>) => void;
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* Canonicalize a `git push` command's destination ref to `refs/heads/<name>`.
|
|
77
|
+
* Two-tier (§3.1): explicit refspec / local @{push} fast path (no network);
|
|
78
|
+
* `git push --dry-run --porcelain` only for the ambiguous case, timeout-bounded.
|
|
79
|
+
* Returns null when no branch key is derivable (detached, tag, delete, resolver
|
|
80
|
+
* error/timeout) → the caller FAILS OPEN (does not gate).
|
|
81
|
+
*/
|
|
82
|
+
export declare function canonicalPushKey(command: string, cwd: string, opts?: {
|
|
83
|
+
execTimeoutMs?: number;
|
|
84
|
+
}): string | null;
|
|
85
|
+
export declare class PrHandLease {
|
|
86
|
+
private readonly d;
|
|
87
|
+
private readonly filePath;
|
|
88
|
+
private readonly lockPath;
|
|
89
|
+
private readonly now;
|
|
90
|
+
private failOpenCounts;
|
|
91
|
+
constructor(deps: PrHandLeaseDeps);
|
|
92
|
+
/** The path the BackupManager denylist must exclude (ephemeral, never restored). */
|
|
93
|
+
static stateFileRelPath(): string;
|
|
94
|
+
/**
|
|
95
|
+
* Evaluate a push against the lease for `key` (from canonicalPushKey).
|
|
96
|
+
* Returns the chokepoint decision. NEVER throws — any internal error resolves
|
|
97
|
+
* to allow (the hook's own-crash fail-open is the outer guarantee; this is the
|
|
98
|
+
* inner one).
|
|
99
|
+
*/
|
|
100
|
+
evaluate(key: string, myTopicId: number, mySessionId: string): LeaseEvalResult;
|
|
101
|
+
/** Acquire or renew the lease for `key` for my (topic, session, machine). Atomic CAS under the lock. */
|
|
102
|
+
acquireOrRenew(key: string, holder: {
|
|
103
|
+
topicId: number;
|
|
104
|
+
sessionId: string;
|
|
105
|
+
intent?: LeaseIntent;
|
|
106
|
+
prNumber?: number | null;
|
|
107
|
+
dryRun?: boolean;
|
|
108
|
+
}): PrHandLeaseRecord;
|
|
109
|
+
/**
|
|
110
|
+
* Atomic-CAS takeover of a stale lease (§3.3/B3). Writes my record only if the
|
|
111
|
+
* on-disk record still matches the observed (holderTopicId, acquiredAt). Returns
|
|
112
|
+
* the new record on success, or null if another hand healed first (loser yields).
|
|
113
|
+
*/
|
|
114
|
+
takeOverIfStale(key: string, observed: {
|
|
115
|
+
holderTopicId: number;
|
|
116
|
+
acquiredAt: number;
|
|
117
|
+
}, holder: {
|
|
118
|
+
topicId: number;
|
|
119
|
+
sessionId: string;
|
|
120
|
+
intent?: LeaseIntent;
|
|
121
|
+
prNumber?: number | null;
|
|
122
|
+
dryRun?: boolean;
|
|
123
|
+
}): PrHandLeaseRecord | null;
|
|
124
|
+
/** Release my lease (terminal status), tombstoned briefly to guard the re-grab race (§3.7). */
|
|
125
|
+
release(key: string, topicId: number, status: LeaseTombstoneStatus): void;
|
|
126
|
+
/** Read view for GET /pr-leases — each record + its DERIVED (honest) liveness. */
|
|
127
|
+
list(): Array<PrHandLeaseRecord & {
|
|
128
|
+
key: string;
|
|
129
|
+
liveness: DerivedLeaseLiveness;
|
|
130
|
+
}>;
|
|
131
|
+
private derivedLiveness;
|
|
132
|
+
/**
|
|
133
|
+
* Raw same-machine liveness probe: is the holder's tmux session in the
|
|
134
|
+
* in-memory running set? Same key at write + lookup (M-C). On probe error,
|
|
135
|
+
* fail toward LIVE (yield) — uncertainty about the probe must not seize a
|
|
136
|
+
* holder; the caller's past-ceiling path handles a persistently-wedged probe.
|
|
137
|
+
*/
|
|
138
|
+
private isSessionRunning;
|
|
139
|
+
private acquireUnlocked;
|
|
140
|
+
/** Read with fail-OPEN on corrupt/absent (§3.4 step 1 / M10). */
|
|
141
|
+
private readAll;
|
|
142
|
+
private readAllUnlocked;
|
|
143
|
+
private pruneExpiredTombstones;
|
|
144
|
+
private persist;
|
|
145
|
+
/** One process-wide lock (matching ResumeQueue's single lockPath); 'wx' first-writer-wins. */
|
|
146
|
+
private withLock;
|
|
147
|
+
private recordFailOpen;
|
|
148
|
+
private attention;
|
|
149
|
+
private audit;
|
|
150
|
+
}
|
|
151
|
+
//# sourceMappingURL=PrHandLease.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"PrHandLease.d.ts","sourceRoot":"","sources":["../../src/core/PrHandLease.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,448 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* PrHandLease — per-branch ownership lease so two of the agent's OWN concurrent
|
|
3
|
+
* sessions ("hands") cannot push competing commits to the same branch.
|
|
4
|
+
*
|
|
5
|
+
* Spec: docs/specs/parallel-hand-pr-lease.md (review-convergence + approved).
|
|
6
|
+
* Closes the push-competition cause of the 2026-06-15 PR #1183 merge thrash.
|
|
7
|
+
*
|
|
8
|
+
* Design anchors (from the converged spec):
|
|
9
|
+
* - Identity = holderTopicId (stable across the constant session respawns);
|
|
10
|
+
* holderSessionId is a LIVENESS-PROBE HANDLE ONLY, never the identity (§3.2/B2).
|
|
11
|
+
* - ONE process-wide lock guards the single JSON file (matching ResumeQueue's
|
|
12
|
+
* single lockPath); per-record compare-and-swap under that lock (§3.3/B3/M-D).
|
|
13
|
+
* - Liveness probe is TTL-gated (only when a lease is past ttl) and reads the
|
|
14
|
+
* in-memory running set — never a tmux exec (§3.5/M4).
|
|
15
|
+
* - A holder on a DIFFERENT machine is NEVER judged dead from local session
|
|
16
|
+
* absence (§3.5/M6); foreign-machine holder → fail-closed → treat as live.
|
|
17
|
+
* - maxHold ceiling is liveness-discriminated: a DEAD/foreign-unverified holder
|
|
18
|
+
* past the ceiling is CAS-seized + attention; a LIVE same-machine holder past
|
|
19
|
+
* the ceiling is NOT seized — the caller escalates instead (§3.9/codex#3).
|
|
20
|
+
* - Unreadable/corrupt/absent state file → fail-OPEN (treat as no lease) (§3.4/M10).
|
|
21
|
+
* - dryRun leases carry dryRun:true; non-acquisition readers MUST ignore them (§5).
|
|
22
|
+
*
|
|
23
|
+
* This module is the STORE + the pure key-derivation helpers. The PreToolUse Bash
|
|
24
|
+
* hook (pr-hand-lease-guard.js) and the GET /pr-leases route consume it. Enforcement
|
|
25
|
+
* is the hook's (the real chokepoint where agent `git push` runs); SafeGitExecutor
|
|
26
|
+
* carries the same check as defense-in-depth for instar's own internal pushes.
|
|
27
|
+
*/
|
|
28
|
+
import fs from 'node:fs';
|
|
29
|
+
import path from 'node:path';
|
|
30
|
+
import os from 'node:os';
|
|
31
|
+
import { SafeGitExecutor } from './SafeGitExecutor.js';
|
|
32
|
+
import { SafeFsExecutor } from './SafeFsExecutor.js';
|
|
33
|
+
const DEFAULT_TTL_MS = 30 * 60 * 1000; // 30m dead-holder backstop
|
|
34
|
+
const DEFAULT_MAX_HOLD_MS = 90 * 60 * 1000; // 90m absolute ceiling
|
|
35
|
+
const TOMBSTONE_WINDOW_MS = 5 * 1000; // ≤5s re-grab guard
|
|
36
|
+
/**
|
|
37
|
+
* Canonicalize a `git push` command's destination ref to `refs/heads/<name>`.
|
|
38
|
+
* Two-tier (§3.1): explicit refspec / local @{push} fast path (no network);
|
|
39
|
+
* `git push --dry-run --porcelain` only for the ambiguous case, timeout-bounded.
|
|
40
|
+
* Returns null when no branch key is derivable (detached, tag, delete, resolver
|
|
41
|
+
* error/timeout) → the caller FAILS OPEN (does not gate).
|
|
42
|
+
*/
|
|
43
|
+
export function canonicalPushKey(command, cwd, opts) {
|
|
44
|
+
// Extract the git push invocation from a possibly-composite command
|
|
45
|
+
// (cd && git push, env-prefix, git -C path push, command git push, multiline).
|
|
46
|
+
// We do not try to defeat obfuscation/aliases/script-bodies — that is an
|
|
47
|
+
// accepted residual evasion of a cooperative guard (§2 non-goal).
|
|
48
|
+
const pushMatch = command.match(/\bgit\b[^\n;&|]*\bpush\b([^\n;&|]*)/);
|
|
49
|
+
if (!pushMatch)
|
|
50
|
+
return null;
|
|
51
|
+
const tail = pushMatch[1] ?? '';
|
|
52
|
+
// Ref deletion → no commit content → not gated.
|
|
53
|
+
if (/--delete\b/.test(tail) || /(^|\s):refs?\/|(^|\s):\S/.test(tail))
|
|
54
|
+
return null;
|
|
55
|
+
// -C <dir> overrides cwd for resolution.
|
|
56
|
+
const cMatch = command.match(/\bgit\b\s+(?:[^\n]*?\s)?-C\s+(\S+)/);
|
|
57
|
+
const effectiveCwd = cMatch ? resolveDir(cwd, stripQuotes(cMatch[1])) : cwd;
|
|
58
|
+
// Fast path: an explicit refspec token (last non-flag arg that isn't the remote).
|
|
59
|
+
const explicit = parseExplicitRefspec(tail);
|
|
60
|
+
if (explicit)
|
|
61
|
+
return `branch:${explicit}`;
|
|
62
|
+
// No explicit refspec → resolve the push destination locally via git's own
|
|
63
|
+
// ref resolution (no network — `rev-parse @{push}` reads config only). If that
|
|
64
|
+
// can't resolve it (no upstream / ambiguous push.default), FAIL-OPEN (no key):
|
|
65
|
+
// we never contact the remote from the push hot-path, and an unresolvable ref is
|
|
66
|
+
// the safe direction (the push proceeds). This deliberately drops the earlier
|
|
67
|
+
// remote-contacting `push --dry-run` fallback — it removes the hang surface the
|
|
68
|
+
// round-4 review flagged AND keeps the resolver off the network entirely.
|
|
69
|
+
const local = resolveLocalPushRef(effectiveCwd, opts?.execTimeoutMs);
|
|
70
|
+
return local ? `branch:${local}` : null;
|
|
71
|
+
}
|
|
72
|
+
function stripQuotes(s) {
|
|
73
|
+
return s.replace(/^['"]|['"]$/g, '');
|
|
74
|
+
}
|
|
75
|
+
function resolveDir(cwd, dir) {
|
|
76
|
+
return path.isAbsolute(dir) ? dir : path.resolve(cwd, dir);
|
|
77
|
+
}
|
|
78
|
+
/** Parse `origin foo` / `origin HEAD:foo` / `origin HEAD:refs/heads/foo` → refs/heads/foo. */
|
|
79
|
+
function parseExplicitRefspec(tail) {
|
|
80
|
+
// Drop flags; tokens left are [remote] [refspec...].
|
|
81
|
+
const tokens = tail.split(/\s+/).filter((t) => t && !t.startsWith('-'));
|
|
82
|
+
// remote is the first bare token; a refspec is any token containing ':' or a bare branch after the remote.
|
|
83
|
+
for (const tok of tokens) {
|
|
84
|
+
const t = stripQuotes(tok);
|
|
85
|
+
if (t.includes(':')) {
|
|
86
|
+
const dst = t.split(':')[1];
|
|
87
|
+
return normalizeHeadsRef(dst);
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
// bare `git push origin foo` → tokens [origin, foo]; foo is the destination branch.
|
|
91
|
+
if (tokens.length >= 2) {
|
|
92
|
+
return normalizeHeadsRef(stripQuotes(tokens[1]));
|
|
93
|
+
}
|
|
94
|
+
return null;
|
|
95
|
+
}
|
|
96
|
+
function normalizeHeadsRef(ref) {
|
|
97
|
+
if (!ref)
|
|
98
|
+
return null;
|
|
99
|
+
if (ref.startsWith('refs/heads/'))
|
|
100
|
+
return ref;
|
|
101
|
+
if (ref.startsWith('refs/'))
|
|
102
|
+
return null; // tag/non-heads → not gated
|
|
103
|
+
if (ref === 'HEAD')
|
|
104
|
+
return null; // unresolved here; local resolver handles it
|
|
105
|
+
return `refs/heads/${ref}`;
|
|
106
|
+
}
|
|
107
|
+
function resolveLocalPushRef(cwd, timeoutMs) {
|
|
108
|
+
try {
|
|
109
|
+
const out = SafeGitExecutor.readSync(['rev-parse', '--symbolic-full-name', '@{push}'], {
|
|
110
|
+
cwd,
|
|
111
|
+
operation: 'pr-hand-lease canonical-key resolve',
|
|
112
|
+
encoding: 'utf-8',
|
|
113
|
+
timeout: timeoutMs ?? 2000,
|
|
114
|
+
stdio: ['ignore', 'pipe', 'ignore'],
|
|
115
|
+
env: { ...process.env, GIT_TERMINAL_PROMPT: '0' },
|
|
116
|
+
}).trim();
|
|
117
|
+
if (out.startsWith('refs/remotes/')) {
|
|
118
|
+
// refs/remotes/<remote>/<branch> → refs/heads/<branch>
|
|
119
|
+
const parts = out.split('/');
|
|
120
|
+
const branch = parts.slice(3).join('/');
|
|
121
|
+
return branch ? `refs/heads/${branch}` : null;
|
|
122
|
+
}
|
|
123
|
+
if (out.startsWith('refs/heads/'))
|
|
124
|
+
return out;
|
|
125
|
+
return null;
|
|
126
|
+
}
|
|
127
|
+
catch {
|
|
128
|
+
// @silent-fallback-ok: no upstream / unresolvable push.default → no key → caller FAILS OPEN
|
|
129
|
+
// (the push proceeds). We never contact the remote from the push hot-path.
|
|
130
|
+
return null;
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
export class PrHandLease {
|
|
134
|
+
d;
|
|
135
|
+
filePath;
|
|
136
|
+
lockPath;
|
|
137
|
+
now;
|
|
138
|
+
failOpenCounts = new Map();
|
|
139
|
+
constructor(deps) {
|
|
140
|
+
this.d = deps;
|
|
141
|
+
const root = path.join(deps.stateDir, 'state');
|
|
142
|
+
this.filePath = path.join(root, 'pr-hand-leases.json');
|
|
143
|
+
this.lockPath = path.join(root, 'pr-hand-leases.lock');
|
|
144
|
+
this.now = deps.now ?? (() => Date.now());
|
|
145
|
+
}
|
|
146
|
+
/** The path the BackupManager denylist must exclude (ephemeral, never restored). */
|
|
147
|
+
static stateFileRelPath() {
|
|
148
|
+
return 'state/pr-hand-leases.json';
|
|
149
|
+
}
|
|
150
|
+
/**
|
|
151
|
+
* Evaluate a push against the lease for `key` (from canonicalPushKey).
|
|
152
|
+
* Returns the chokepoint decision. NEVER throws — any internal error resolves
|
|
153
|
+
* to allow (the hook's own-crash fail-open is the outer guarantee; this is the
|
|
154
|
+
* inner one).
|
|
155
|
+
*/
|
|
156
|
+
evaluate(key, myTopicId, mySessionId) {
|
|
157
|
+
try {
|
|
158
|
+
const all = this.readAll(); // fail-open on corrupt → {}
|
|
159
|
+
const rec = all[key];
|
|
160
|
+
if (!rec || rec.tombstone) {
|
|
161
|
+
return { decision: 'allow', reason: rec?.tombstone ? 'tombstoned-free' : 'no-lease' };
|
|
162
|
+
}
|
|
163
|
+
if (rec.holderTopicId === myTopicId) {
|
|
164
|
+
return { decision: 'allow', reason: 'own-topic', holder: rec };
|
|
165
|
+
}
|
|
166
|
+
// dryRun leases never block a different hand (observe-only).
|
|
167
|
+
if (rec.dryRun) {
|
|
168
|
+
return { decision: 'allow', reason: 'foreign-dryrun-ignored', holder: rec };
|
|
169
|
+
}
|
|
170
|
+
const t = this.now();
|
|
171
|
+
const sameMachine = rec.holderMachineId === this.d.machineId;
|
|
172
|
+
const ttlExpired = t - rec.renewedAt > rec.ttlMs;
|
|
173
|
+
const pastCeiling = t - rec.acquiredAt > rec.maxHoldMs;
|
|
174
|
+
// Ceiling override FIRST (§3.9 precedence — overrides foreign-machine conservatism).
|
|
175
|
+
if (pastCeiling) {
|
|
176
|
+
if (sameMachine && this.isSessionRunning(rec)) {
|
|
177
|
+
// LIVE same-machine holder past ceiling → escalate, do NOT seize (codex#3/§3.9).
|
|
178
|
+
return { decision: 'escalate', reason: 'live-holder-past-ceiling', holder: rec };
|
|
179
|
+
}
|
|
180
|
+
// DEAD same-machine OR foreign-machine-unverified past ceiling → stale → caller seizes (+attention).
|
|
181
|
+
return { decision: 'allow', reason: 'stale-past-ceiling', holder: rec };
|
|
182
|
+
}
|
|
183
|
+
// Within ceiling:
|
|
184
|
+
if (!ttlExpired) {
|
|
185
|
+
// TTL-gate: a fresh lease is live without probing.
|
|
186
|
+
return { decision: 'deny', reason: 'live-foreign-lease', holder: rec };
|
|
187
|
+
}
|
|
188
|
+
if (!sameMachine) {
|
|
189
|
+
// Foreign-machine holder within ceiling, past TTL → NEVER judged dead from local
|
|
190
|
+
// session absence → yield (§3.5/M6).
|
|
191
|
+
return { decision: 'deny', reason: 'foreign-machine-within-ceiling', holder: rec };
|
|
192
|
+
}
|
|
193
|
+
// Same-machine, TTL-expired → probe the in-memory running set.
|
|
194
|
+
if (this.isSessionRunning(rec)) {
|
|
195
|
+
return { decision: 'deny', reason: 'live-foreign-lease', holder: rec };
|
|
196
|
+
}
|
|
197
|
+
return { decision: 'allow', reason: 'stale-dead', holder: rec };
|
|
198
|
+
}
|
|
199
|
+
catch (err) {
|
|
200
|
+
// Inner fail-open — never block on an internal error.
|
|
201
|
+
this.audit({ event: 'evaluate-error', key, error: String(err) });
|
|
202
|
+
return { decision: 'allow', reason: 'eval-error-failopen' };
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
/** Acquire or renew the lease for `key` for my (topic, session, machine). Atomic CAS under the lock. */
|
|
206
|
+
acquireOrRenew(key, holder) {
|
|
207
|
+
return this.withLock(() => {
|
|
208
|
+
const all = this.readAllUnlocked();
|
|
209
|
+
const existing = all[key];
|
|
210
|
+
const t = this.now();
|
|
211
|
+
if (existing && !existing.tombstone && existing.holderTopicId === holder.topicId) {
|
|
212
|
+
existing.renewedAt = t;
|
|
213
|
+
existing.holderSessionId = holder.sessionId;
|
|
214
|
+
if (holder.intent)
|
|
215
|
+
existing.intent = holder.intent;
|
|
216
|
+
if (holder.prNumber !== undefined)
|
|
217
|
+
existing.prNumber = holder.prNumber;
|
|
218
|
+
if (holder.dryRun !== undefined)
|
|
219
|
+
existing.dryRun = holder.dryRun;
|
|
220
|
+
this.persist(all);
|
|
221
|
+
this.audit({ event: 'renew', key, topicId: holder.topicId, dryRun: !!holder.dryRun });
|
|
222
|
+
return existing;
|
|
223
|
+
}
|
|
224
|
+
const rec = {
|
|
225
|
+
holderTopicId: holder.topicId,
|
|
226
|
+
holderSessionId: holder.sessionId,
|
|
227
|
+
holderMachineId: this.d.machineId,
|
|
228
|
+
prNumber: holder.prNumber ?? null,
|
|
229
|
+
intent: holder.intent ?? 'build',
|
|
230
|
+
acquiredAt: t,
|
|
231
|
+
renewedAt: t,
|
|
232
|
+
ttlMs: DEFAULT_TTL_MS,
|
|
233
|
+
maxHoldMs: DEFAULT_MAX_HOLD_MS,
|
|
234
|
+
dryRun: holder.dryRun || undefined,
|
|
235
|
+
};
|
|
236
|
+
all[key] = rec;
|
|
237
|
+
this.persist(all);
|
|
238
|
+
this.audit({ event: 'acquire', key, topicId: holder.topicId, dryRun: !!holder.dryRun });
|
|
239
|
+
return rec;
|
|
240
|
+
});
|
|
241
|
+
}
|
|
242
|
+
/**
|
|
243
|
+
* Atomic-CAS takeover of a stale lease (§3.3/B3). Writes my record only if the
|
|
244
|
+
* on-disk record still matches the observed (holderTopicId, acquiredAt). Returns
|
|
245
|
+
* the new record on success, or null if another hand healed first (loser yields).
|
|
246
|
+
*/
|
|
247
|
+
takeOverIfStale(key, observed, holder) {
|
|
248
|
+
return this.withLock(() => {
|
|
249
|
+
const all = this.readAllUnlocked();
|
|
250
|
+
const cur = all[key];
|
|
251
|
+
if (!cur || cur.tombstone) {
|
|
252
|
+
// Already free → acquire fresh.
|
|
253
|
+
return this.acquireUnlocked(all, key, holder);
|
|
254
|
+
}
|
|
255
|
+
// CAS precondition: the record must be exactly the one we observed as stale.
|
|
256
|
+
if (cur.holderTopicId !== observed.holderTopicId || cur.acquiredAt !== observed.acquiredAt) {
|
|
257
|
+
this.audit({ event: 'takeover-cas-lost', key });
|
|
258
|
+
return null; // another hand healed first → yield
|
|
259
|
+
}
|
|
260
|
+
const forcedRelease = this.now() - cur.acquiredAt > cur.maxHoldMs;
|
|
261
|
+
const rec = this.acquireUnlocked(all, key, holder);
|
|
262
|
+
this.audit({
|
|
263
|
+
event: forcedRelease ? 'auto-heal-ceiling' : 'auto-heal-dead',
|
|
264
|
+
key,
|
|
265
|
+
priorTopicId: observed.holderTopicId,
|
|
266
|
+
priorMachineId: cur.holderMachineId,
|
|
267
|
+
});
|
|
268
|
+
if (forcedRelease || cur.holderMachineId !== this.d.machineId) {
|
|
269
|
+
this.attention('pr-lease-forced-release', `Branch ${key} lease force-released from topic ${observed.holderTopicId} (machine ${cur.holderMachineId}).`);
|
|
270
|
+
}
|
|
271
|
+
return rec;
|
|
272
|
+
});
|
|
273
|
+
}
|
|
274
|
+
/** Release my lease (terminal status), tombstoned briefly to guard the re-grab race (§3.7). */
|
|
275
|
+
release(key, topicId, status) {
|
|
276
|
+
this.withLock(() => {
|
|
277
|
+
const all = this.readAllUnlocked();
|
|
278
|
+
const cur = all[key];
|
|
279
|
+
if (cur && cur.holderTopicId === topicId && !cur.tombstone) {
|
|
280
|
+
cur.tombstone = { status, at: this.now() };
|
|
281
|
+
this.persist(all);
|
|
282
|
+
this.audit({ event: 'release', key, topicId, status });
|
|
283
|
+
}
|
|
284
|
+
return undefined;
|
|
285
|
+
});
|
|
286
|
+
}
|
|
287
|
+
/** Read view for GET /pr-leases — each record + its DERIVED (honest) liveness. */
|
|
288
|
+
list() {
|
|
289
|
+
const all = this.readAll();
|
|
290
|
+
const out = [];
|
|
291
|
+
for (const [key, rec] of Object.entries(all)) {
|
|
292
|
+
out.push({ ...rec, key, liveness: this.derivedLiveness(rec) });
|
|
293
|
+
}
|
|
294
|
+
return out;
|
|
295
|
+
}
|
|
296
|
+
// ---- internals ----
|
|
297
|
+
derivedLiveness(rec) {
|
|
298
|
+
if (rec.tombstone)
|
|
299
|
+
return 'tombstoned';
|
|
300
|
+
if (rec.holderMachineId !== this.d.machineId)
|
|
301
|
+
return 'foreign-machine';
|
|
302
|
+
const ttlExpired = this.now() - rec.renewedAt > rec.ttlMs;
|
|
303
|
+
if (!ttlExpired)
|
|
304
|
+
return 'live';
|
|
305
|
+
return this.isSessionRunning(rec) ? 'live' : 'stale-dead';
|
|
306
|
+
}
|
|
307
|
+
/**
|
|
308
|
+
* Raw same-machine liveness probe: is the holder's tmux session in the
|
|
309
|
+
* in-memory running set? Same key at write + lookup (M-C). On probe error,
|
|
310
|
+
* fail toward LIVE (yield) — uncertainty about the probe must not seize a
|
|
311
|
+
* holder; the caller's past-ceiling path handles a persistently-wedged probe.
|
|
312
|
+
*/
|
|
313
|
+
isSessionRunning(rec) {
|
|
314
|
+
try {
|
|
315
|
+
return this.d.runningSessionNames().includes(rec.holderSessionId);
|
|
316
|
+
}
|
|
317
|
+
catch {
|
|
318
|
+
// @silent-fallback-ok: probe unavailable → treat live (yield), bounded by the ceiling override.
|
|
319
|
+
return true;
|
|
320
|
+
}
|
|
321
|
+
}
|
|
322
|
+
acquireUnlocked(all, key, holder) {
|
|
323
|
+
const t = this.now();
|
|
324
|
+
const rec = {
|
|
325
|
+
holderTopicId: holder.topicId,
|
|
326
|
+
holderSessionId: holder.sessionId,
|
|
327
|
+
holderMachineId: this.d.machineId,
|
|
328
|
+
prNumber: holder.prNumber ?? null,
|
|
329
|
+
intent: holder.intent ?? 'build',
|
|
330
|
+
acquiredAt: t,
|
|
331
|
+
renewedAt: t,
|
|
332
|
+
ttlMs: DEFAULT_TTL_MS,
|
|
333
|
+
maxHoldMs: DEFAULT_MAX_HOLD_MS,
|
|
334
|
+
dryRun: holder.dryRun || undefined,
|
|
335
|
+
};
|
|
336
|
+
all[key] = rec;
|
|
337
|
+
this.persist(all);
|
|
338
|
+
return rec;
|
|
339
|
+
}
|
|
340
|
+
/** Read with fail-OPEN on corrupt/absent (§3.4 step 1 / M10). */
|
|
341
|
+
readAll() {
|
|
342
|
+
try {
|
|
343
|
+
if (!fs.existsSync(this.filePath))
|
|
344
|
+
return {};
|
|
345
|
+
const raw = fs.readFileSync(this.filePath, 'utf-8');
|
|
346
|
+
const parsed = JSON.parse(raw);
|
|
347
|
+
return this.pruneExpiredTombstones(parsed);
|
|
348
|
+
}
|
|
349
|
+
catch (err) {
|
|
350
|
+
// @silent-fallback-ok: corrupt/torn/absent lease file → fail-OPEN (treat as no lease,
|
|
351
|
+
// the push proceeds — a missing lease must NEVER block all pushes). NOT silent:
|
|
352
|
+
// recordFailOpen() logs every occurrence and raises an attention item on recurrence.
|
|
353
|
+
this.recordFailOpen('readAll');
|
|
354
|
+
return {};
|
|
355
|
+
}
|
|
356
|
+
}
|
|
357
|
+
readAllUnlocked() {
|
|
358
|
+
return this.readAll();
|
|
359
|
+
}
|
|
360
|
+
pruneExpiredTombstones(all) {
|
|
361
|
+
const t = this.now();
|
|
362
|
+
for (const [key, rec] of Object.entries(all)) {
|
|
363
|
+
if (rec.tombstone && t - rec.tombstone.at > TOMBSTONE_WINDOW_MS)
|
|
364
|
+
delete all[key];
|
|
365
|
+
}
|
|
366
|
+
return all;
|
|
367
|
+
}
|
|
368
|
+
persist(all) {
|
|
369
|
+
const dir = path.dirname(this.filePath);
|
|
370
|
+
fs.mkdirSync(dir, { recursive: true });
|
|
371
|
+
const tmp = `${this.filePath}.${process.pid}.tmp`;
|
|
372
|
+
const fd = fs.openSync(tmp, 'w');
|
|
373
|
+
try {
|
|
374
|
+
fs.writeSync(fd, JSON.stringify(all, null, 2));
|
|
375
|
+
fs.fsyncSync(fd);
|
|
376
|
+
}
|
|
377
|
+
finally {
|
|
378
|
+
fs.closeSync(fd);
|
|
379
|
+
}
|
|
380
|
+
fs.renameSync(tmp, this.filePath); // atomic swap — readers never see a torn file
|
|
381
|
+
}
|
|
382
|
+
/** One process-wide lock (matching ResumeQueue's single lockPath); 'wx' first-writer-wins. */
|
|
383
|
+
withLock(fn) {
|
|
384
|
+
const dir = path.dirname(this.lockPath);
|
|
385
|
+
fs.mkdirSync(dir, { recursive: true });
|
|
386
|
+
const deadline = this.now() + 5000;
|
|
387
|
+
// simple spin with O_EXCL; the critical section is a sub-ms file rewrite.
|
|
388
|
+
for (;;) {
|
|
389
|
+
let fd = null;
|
|
390
|
+
try {
|
|
391
|
+
fd = fs.openSync(this.lockPath, 'wx');
|
|
392
|
+
fs.writeSync(fd, JSON.stringify({ pid: process.pid, host: os.hostname(), at: this.now() }));
|
|
393
|
+
fs.closeSync(fd);
|
|
394
|
+
fd = null;
|
|
395
|
+
try {
|
|
396
|
+
return fn();
|
|
397
|
+
}
|
|
398
|
+
finally {
|
|
399
|
+
try {
|
|
400
|
+
SafeFsExecutor.safeUnlinkSync(this.lockPath, { operation: 'PrHandLease lock release' });
|
|
401
|
+
}
|
|
402
|
+
catch { /* @silent-fallback-ok: lock cleanup best-effort */ }
|
|
403
|
+
}
|
|
404
|
+
}
|
|
405
|
+
catch (err) {
|
|
406
|
+
if (fd !== null) {
|
|
407
|
+
try {
|
|
408
|
+
fs.closeSync(fd);
|
|
409
|
+
}
|
|
410
|
+
catch { /* ignore */ }
|
|
411
|
+
}
|
|
412
|
+
if (err?.code === 'EEXIST') {
|
|
413
|
+
// Stale lock recovery: if the lock is older than the deadline window, steal it.
|
|
414
|
+
if (this.now() > deadline) {
|
|
415
|
+
try {
|
|
416
|
+
SafeFsExecutor.safeUnlinkSync(this.lockPath, { operation: 'PrHandLease stale-lock steal' });
|
|
417
|
+
}
|
|
418
|
+
catch { /* ignore */ }
|
|
419
|
+
continue;
|
|
420
|
+
}
|
|
421
|
+
continue; // retry
|
|
422
|
+
}
|
|
423
|
+
throw err;
|
|
424
|
+
}
|
|
425
|
+
}
|
|
426
|
+
}
|
|
427
|
+
recordFailOpen(where) {
|
|
428
|
+
const n = (this.failOpenCounts.get(where) ?? 0) + 1;
|
|
429
|
+
this.failOpenCounts.set(where, n);
|
|
430
|
+
this.audit({ event: 'fail-open', where, count: n });
|
|
431
|
+
if (n >= 3) {
|
|
432
|
+
this.attention('pr-lease-failopen', `pr-hand-leases.json repeatedly unreadable (${n}x at ${where}) — lease protection degraded; check the state file.`);
|
|
433
|
+
}
|
|
434
|
+
}
|
|
435
|
+
attention(kind, detail) {
|
|
436
|
+
try {
|
|
437
|
+
this.d.onAttention?.({ kind, detail });
|
|
438
|
+
}
|
|
439
|
+
catch { /* @silent-fallback-ok */ }
|
|
440
|
+
}
|
|
441
|
+
audit(row) {
|
|
442
|
+
try {
|
|
443
|
+
this.d.onAudit?.({ ...row, ts: new Date(this.now()).toISOString() });
|
|
444
|
+
}
|
|
445
|
+
catch { /* @silent-fallback-ok */ }
|
|
446
|
+
}
|
|
447
|
+
}
|
|
448
|
+
//# sourceMappingURL=PrHandLease.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"PrHandLease.js","sourceRoot":"","sources":["../../src/core/PrHandLease.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"devGatedFeatures.d.ts","sourceRoot":"","sources":["../../src/core/devGatedFeatures.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AAEH,oEAAoE;AACpE,MAAM,WAAW,eAAe;IAC9B,mEAAmE;IACnE,IAAI,EAAE,MAAM,CAAC;IACb,uEAAuE;IACvE,UAAU,EAAE,MAAM,CAAC;IACnB,6DAA6D;IAC7D,WAAW,EAAE,MAAM,CAAC;IACpB;;;;;;OAMG;IACH,aAAa,EAAE,MAAM,CAAC;CACvB;AAED,eAAO,MAAM,kBAAkB,EAAE,eAAe,
|
|
1
|
+
{"version":3,"file":"devGatedFeatures.d.ts","sourceRoot":"","sources":["../../src/core/devGatedFeatures.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AAEH,oEAAoE;AACpE,MAAM,WAAW,eAAe;IAC9B,mEAAmE;IACnE,IAAI,EAAE,MAAM,CAAC;IACb,uEAAuE;IACvE,UAAU,EAAE,MAAM,CAAC;IACnB,6DAA6D;IAC7D,WAAW,EAAE,MAAM,CAAC;IACpB;;;;;;OAMG;IACH,aAAa,EAAE,MAAM,CAAC;CACvB;AAED,eAAO,MAAM,kBAAkB,EAAE,eAAe,EA2T/C,CAAC;AAEF;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,MAAM,MAAM,gBAAgB,GACxB,aAAa,GACb,cAAc,GACd,gBAAgB,GAChB,sBAAsB,GACtB,iBAAiB,CAAC;AAEtB,MAAM,WAAW,iBAAiB;IAChC,uEAAuE;IACvE,UAAU,EAAE,MAAM,CAAC;IACnB,6CAA6C;IAC7C,QAAQ,EAAE,gBAAgB,CAAC;IAC3B,mFAAmF;IACnF,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,eAAO,MAAM,oBAAoB,EAAE,iBAAiB,EAuHnD,CAAC;AAEF;;;GAGG;AACH,wBAAgB,eAAe,CAAC,MAAM,EAAE,OAAO,EAAE,UAAU,EAAE,MAAM,GAAG,OAAO,CAO5E"}
|