taskflow-mcp-core 0.3.0-beta.1.2 → 1.0.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.
- package/CONTROL_GUIDE.md +113 -0
- package/README.md +34 -25
- package/dist/control/admission-service.d.ts +15 -0
- package/dist/control/admission-service.d.ts.map +1 -0
- package/dist/control/admission-service.js +64 -0
- package/dist/control/admission-service.js.map +1 -0
- package/dist/control/approval-edits.d.ts +12 -0
- package/dist/control/approval-edits.d.ts.map +1 -0
- package/dist/control/approval-edits.js +66 -0
- package/dist/control/approval-edits.js.map +1 -0
- package/dist/control/approval-service.d.ts +173 -0
- package/dist/control/approval-service.d.ts.map +1 -0
- package/dist/control/approval-service.js +342 -0
- package/dist/control/approval-service.js.map +1 -0
- package/dist/control/authorization.d.ts +94 -0
- package/dist/control/authorization.d.ts.map +1 -0
- package/dist/control/authorization.js +302 -0
- package/dist/control/authorization.js.map +1 -0
- package/dist/control/control-cli.d.ts +3 -0
- package/dist/control/control-cli.d.ts.map +1 -0
- package/dist/control/control-cli.js +279 -0
- package/dist/control/control-cli.js.map +1 -0
- package/dist/control/control-console.d.ts +17 -0
- package/dist/control/control-console.d.ts.map +1 -0
- package/dist/control/control-console.js +67 -0
- package/dist/control/control-console.js.map +1 -0
- package/dist/control/control-host.d.ts +98 -0
- package/dist/control/control-host.d.ts.map +1 -0
- package/dist/control/control-host.js +459 -0
- package/dist/control/control-host.js.map +1 -0
- package/dist/control/control-mcp.d.ts +11 -0
- package/dist/control/control-mcp.d.ts.map +1 -0
- package/dist/control/control-mcp.js +78 -0
- package/dist/control/control-mcp.js.map +1 -0
- package/dist/control/errors.d.ts +44 -0
- package/dist/control/errors.d.ts.map +1 -0
- package/dist/control/errors.js +93 -0
- package/dist/control/errors.js.map +1 -0
- package/dist/control/hello.d.ts +39 -0
- package/dist/control/hello.d.ts.map +1 -0
- package/dist/control/hello.js +80 -0
- package/dist/control/hello.js.map +1 -0
- package/dist/control/host-runtime.d.ts +32 -0
- package/dist/control/host-runtime.d.ts.map +1 -0
- package/dist/control/host-runtime.js +542 -0
- package/dist/control/host-runtime.js.map +1 -0
- package/dist/control/index.d.ts +32 -0
- package/dist/control/index.d.ts.map +1 -0
- package/dist/control/index.js +32 -0
- package/dist/control/index.js.map +1 -0
- package/dist/control/legacy-conflict.d.ts +19 -0
- package/dist/control/legacy-conflict.d.ts.map +1 -0
- package/dist/control/legacy-conflict.js +176 -0
- package/dist/control/legacy-conflict.js.map +1 -0
- package/dist/control/local-bootstrap.d.ts +21 -0
- package/dist/control/local-bootstrap.d.ts.map +1 -0
- package/dist/control/local-bootstrap.js +224 -0
- package/dist/control/local-bootstrap.js.map +1 -0
- package/dist/control/modes.d.ts +60 -0
- package/dist/control/modes.d.ts.map +1 -0
- package/dist/control/modes.js +86 -0
- package/dist/control/modes.js.map +1 -0
- package/dist/control/project-admin-cli.d.ts +3 -0
- package/dist/control/project-admin-cli.d.ts.map +1 -0
- package/dist/control/project-admin-cli.js +155 -0
- package/dist/control/project-admin-cli.js.map +1 -0
- package/dist/control/project-registry.d.ts +20 -0
- package/dist/control/project-registry.d.ts.map +1 -0
- package/dist/control/project-registry.js +181 -0
- package/dist/control/project-registry.js.map +1 -0
- package/dist/control/runtime-checkpoint.d.ts +11 -0
- package/dist/control/runtime-checkpoint.d.ts.map +1 -0
- package/dist/control/runtime-checkpoint.js +39 -0
- package/dist/control/runtime-checkpoint.js.map +1 -0
- package/dist/control/runtime-provider.d.ts +100 -0
- package/dist/control/runtime-provider.d.ts.map +1 -0
- package/dist/control/runtime-provider.js +258 -0
- package/dist/control/runtime-provider.js.map +1 -0
- package/dist/control/schema/approval.d.ts +108 -0
- package/dist/control/schema/approval.d.ts.map +1 -0
- package/dist/control/schema/approval.js +65 -0
- package/dist/control/schema/approval.js.map +1 -0
- package/dist/control/schema/commands.d.ts +663 -0
- package/dist/control/schema/commands.d.ts.map +1 -0
- package/dist/control/schema/commands.js +147 -0
- package/dist/control/schema/commands.js.map +1 -0
- package/dist/control/schema/common.d.ts +24 -0
- package/dist/control/schema/common.d.ts.map +1 -0
- package/dist/control/schema/common.js +38 -0
- package/dist/control/schema/common.js.map +1 -0
- package/dist/control/schema/coordinator.d.ts +98 -0
- package/dist/control/schema/coordinator.d.ts.map +1 -0
- package/dist/control/schema/coordinator.js +87 -0
- package/dist/control/schema/coordinator.js.map +1 -0
- package/dist/control/schema/evidence.d.ts +140 -0
- package/dist/control/schema/evidence.d.ts.map +1 -0
- package/dist/control/schema/evidence.js +64 -0
- package/dist/control/schema/evidence.js.map +1 -0
- package/dist/control/schema/header.d.ts +79 -0
- package/dist/control/schema/header.d.ts.map +1 -0
- package/dist/control/schema/header.js +66 -0
- package/dist/control/schema/header.js.map +1 -0
- package/dist/control/schema/index.d.ts +31 -0
- package/dist/control/schema/index.d.ts.map +1 -0
- package/dist/control/schema/index.js +31 -0
- package/dist/control/schema/index.js.map +1 -0
- package/dist/control/schema/plan.d.ts +291 -0
- package/dist/control/schema/plan.d.ts.map +1 -0
- package/dist/control/schema/plan.js +80 -0
- package/dist/control/schema/plan.js.map +1 -0
- package/dist/control/schema/policy.d.ts +96 -0
- package/dist/control/schema/policy.d.ts.map +1 -0
- package/dist/control/schema/policy.js +73 -0
- package/dist/control/schema/policy.js.map +1 -0
- package/dist/control/schema/run.d.ts +61 -0
- package/dist/control/schema/run.d.ts.map +1 -0
- package/dist/control/schema/run.js +56 -0
- package/dist/control/schema/run.js.map +1 -0
- package/dist/control/schema/te-mirrors.d.ts +145 -0
- package/dist/control/schema/te-mirrors.d.ts.map +1 -0
- package/dist/control/schema/te-mirrors.js +145 -0
- package/dist/control/schema/te-mirrors.js.map +1 -0
- package/dist/control/schema/transport.d.ts +479 -0
- package/dist/control/schema/transport.d.ts.map +1 -0
- package/dist/control/schema/transport.js +181 -0
- package/dist/control/schema/transport.js.map +1 -0
- package/dist/control/singleton.d.ts +135 -0
- package/dist/control/singleton.d.ts.map +1 -0
- package/dist/control/singleton.js +607 -0
- package/dist/control/singleton.js.map +1 -0
- package/dist/control/store/coordinator-store.d.ts +143 -0
- package/dist/control/store/coordinator-store.d.ts.map +1 -0
- package/dist/control/store/coordinator-store.js +620 -0
- package/dist/control/store/coordinator-store.js.map +1 -0
- package/dist/control/store/evidence-adapter.d.ts +10 -0
- package/dist/control/store/evidence-adapter.d.ts.map +1 -0
- package/dist/control/store/evidence-adapter.js +114 -0
- package/dist/control/store/evidence-adapter.js.map +1 -0
- package/dist/control/store/evidence-explanation.d.ts +55 -0
- package/dist/control/store/evidence-explanation.d.ts.map +1 -0
- package/dist/control/store/evidence-explanation.js +50 -0
- package/dist/control/store/evidence-explanation.js.map +1 -0
- package/dist/control/store/evidence-store.d.ts +143 -0
- package/dist/control/store/evidence-store.d.ts.map +1 -0
- package/dist/control/store/evidence-store.js +437 -0
- package/dist/control/store/evidence-store.js.map +1 -0
- package/dist/control/store/index.d.ts +3 -0
- package/dist/control/store/index.d.ts.map +1 -0
- package/dist/control/store/index.js +2 -0
- package/dist/control/store/index.js.map +1 -0
- package/dist/control/store/journal.d.ts +270 -0
- package/dist/control/store/journal.d.ts.map +1 -0
- package/dist/control/store/journal.js +50 -0
- package/dist/control/store/journal.js.map +1 -0
- package/dist/control/store/project-lifecycle.d.ts +49 -0
- package/dist/control/store/project-lifecycle.d.ts.map +1 -0
- package/dist/control/store/project-lifecycle.js +288 -0
- package/dist/control/store/project-lifecycle.js.map +1 -0
- package/dist/control/store/store.d.ts +93 -0
- package/dist/control/store/store.d.ts.map +1 -0
- package/dist/control/store/store.js +873 -0
- package/dist/control/store/store.js.map +1 -0
- package/dist/control/te-provider.d.ts +86 -0
- package/dist/control/te-provider.d.ts.map +1 -0
- package/dist/control/te-provider.js +131 -0
- package/dist/control/te-provider.js.map +1 -0
- package/dist/control/uds.d.ts +114 -0
- package/dist/control/uds.d.ts.map +1 -0
- package/dist/control/uds.js +456 -0
- package/dist/control/uds.js.map +1 -0
- package/dist/control/web-console/view.d.ts +5 -0
- package/dist/control/web-console/view.d.ts.map +1 -0
- package/dist/control/web-console/view.js +122 -0
- package/dist/control/web-console/view.js.map +1 -0
- package/dist/control/web-console.d.ts +50 -0
- package/dist/control/web-console.d.ts.map +1 -0
- package/dist/control/web-console.js +317 -0
- package/dist/control/web-console.js.map +1 -0
- package/dist/mcp/jsonrpc.d.ts.map +1 -1
- package/dist/mcp/jsonrpc.js +12 -3
- package/dist/mcp/jsonrpc.js.map +1 -1
- package/dist/mcp/server.d.ts.map +1 -1
- package/dist/mcp/server.js +26 -17
- package/dist/mcp/server.js.map +1 -1
- package/package.json +13 -5
|
@@ -0,0 +1,607 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* User singleton lock + coordination endpoint + fencing (P13 / RFC §5.1 D32).
|
|
3
|
+
*
|
|
4
|
+
* Contract implemented here (P13 "排他锁语义" + fresh-install §5.2):
|
|
5
|
+
* - Owner publishes via hard-link create — never rename-overwrite.
|
|
6
|
+
* - Malformed singleton metadata fails closed.
|
|
7
|
+
* - Dead-PID takeover stays fail-closed: reclaim only when the owner is
|
|
8
|
+
* provably dead (liveness probe) AND the record's birth token still matches
|
|
9
|
+
* (PID reuse cannot inherit a live holder's lock).
|
|
10
|
+
* - Collaborative competitors use identity-bound reclaim: fixed claim file +
|
|
11
|
+
* O_EXCL + generation check + rename-to-discard + recoverable claim cleanup.
|
|
12
|
+
* - Release = compare-and-delete on acquire-time device/inode + owner token
|
|
13
|
+
* (rename-to-discard).
|
|
14
|
+
* - Stale endpoint recovery: dead peer ⇒ remove socket file ⇒ restart.
|
|
15
|
+
* - Fencing: every acquire/reclaim bumps the CoordinatorLease epoch; RPCs
|
|
16
|
+
* carrying an older epoch are rejected (TF_AUTHORITY_REVOKED).
|
|
17
|
+
*
|
|
18
|
+
* TE's `resources/*` persistence helpers are deliberately not exported by
|
|
19
|
+
* taskflow-core, so this module re-implements the small POSIX primitives
|
|
20
|
+
* (atomic write, process birth token) with the same fail-closed discipline.
|
|
21
|
+
*/
|
|
22
|
+
import * as crypto from "node:crypto";
|
|
23
|
+
import * as fs from "node:fs";
|
|
24
|
+
import * as os from "node:os";
|
|
25
|
+
import * as path from "node:path";
|
|
26
|
+
import { Value } from "typebox/value";
|
|
27
|
+
import { bootstrapFailed, ControlError } from "./errors.js";
|
|
28
|
+
import { readDurableCoordinatorEpoch } from "./store/coordinator-store.js";
|
|
29
|
+
import { CoordinatorLeaseSchema } from "./schema/coordinator.js";
|
|
30
|
+
// ---------------------------------------------------------------------------
|
|
31
|
+
// Layout (P13): user `~/.taskflow/control/` (TASKFLOW_HOME overridable)
|
|
32
|
+
// ---------------------------------------------------------------------------
|
|
33
|
+
export const TASKFLOW_HOME_ENV = "TASKFLOW_HOME";
|
|
34
|
+
export const DEFAULT_CONTROL_DIR_NAME = "control";
|
|
35
|
+
export function userTaskflowHome(homeOverride) {
|
|
36
|
+
return homeOverride ?? process.env[TASKFLOW_HOME_ENV] ?? path.join(os.homedir(), ".taskflow");
|
|
37
|
+
}
|
|
38
|
+
export function userControlHome(homeOverride) {
|
|
39
|
+
return path.join(userTaskflowHome(homeOverride), DEFAULT_CONTROL_DIR_NAME);
|
|
40
|
+
}
|
|
41
|
+
export function singletonPaths(controlHome) {
|
|
42
|
+
const home = controlHome ?? userControlHome();
|
|
43
|
+
return {
|
|
44
|
+
controlHome: home,
|
|
45
|
+
lockPath: path.join(home, "singleton.lock.json"),
|
|
46
|
+
endpointPath: path.join(home, "taskflow.sock"),
|
|
47
|
+
leasePath: path.join(home, "coordinator-lease.json"),
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
/** Exact, platform-native process-birth identity; never an uptime estimate. */
|
|
51
|
+
export function readProcessBirthToken(pid) {
|
|
52
|
+
if (!Number.isSafeInteger(pid) || pid < 1)
|
|
53
|
+
return undefined;
|
|
54
|
+
try {
|
|
55
|
+
if (process.platform === "linux") {
|
|
56
|
+
const bootId = fs.readFileSync("/proc/sys/kernel/random/boot_id", "utf8").trim();
|
|
57
|
+
const stat = fs.readFileSync(`/proc/${pid}/stat`, "utf8").trim();
|
|
58
|
+
const commandEnd = stat.lastIndexOf(")");
|
|
59
|
+
if (!bootId || commandEnd < 0)
|
|
60
|
+
return undefined;
|
|
61
|
+
const startTicks = stat.slice(commandEnd + 1).trim().split(/\s+/)[19];
|
|
62
|
+
if (!/^\d+$/.test(startTicks ?? ""))
|
|
63
|
+
return undefined;
|
|
64
|
+
return `linux:${bootId}:${startTicks}`;
|
|
65
|
+
}
|
|
66
|
+
return undefined; // macOS/others: fail closed (never reclaim a possibly-live owner)
|
|
67
|
+
}
|
|
68
|
+
catch {
|
|
69
|
+
return undefined;
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
export function defaultProcessIdentity() {
|
|
73
|
+
const native = readProcessBirthToken(process.pid);
|
|
74
|
+
return {
|
|
75
|
+
pid: process.pid,
|
|
76
|
+
birthToken: native ?? `opaque:${crypto.randomUUID()}`,
|
|
77
|
+
birthTokenKind: native === undefined ? "opaque" : "native",
|
|
78
|
+
};
|
|
79
|
+
}
|
|
80
|
+
export function defaultProcessInspector(pid) {
|
|
81
|
+
if (pid === process.pid) {
|
|
82
|
+
const identity = defaultProcessIdentity();
|
|
83
|
+
return { alive: true, birthToken: identity.birthToken, birthTokenKind: identity.birthTokenKind };
|
|
84
|
+
}
|
|
85
|
+
try {
|
|
86
|
+
process.kill(pid, 0);
|
|
87
|
+
const birthToken = readProcessBirthToken(pid);
|
|
88
|
+
return birthToken === undefined
|
|
89
|
+
? { alive: true }
|
|
90
|
+
: { alive: true, birthToken, birthTokenKind: "native" };
|
|
91
|
+
}
|
|
92
|
+
catch (error) {
|
|
93
|
+
const code = error.code;
|
|
94
|
+
if (code !== "EPERM")
|
|
95
|
+
return { alive: false };
|
|
96
|
+
const birthToken = readProcessBirthToken(pid);
|
|
97
|
+
return birthToken === undefined
|
|
98
|
+
? { alive: true }
|
|
99
|
+
: { alive: true, birthToken, birthTokenKind: "native" };
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
// ---------------------------------------------------------------------------
|
|
103
|
+
// Singleton lock record (immutable; published by hard-link create)
|
|
104
|
+
// ---------------------------------------------------------------------------
|
|
105
|
+
export const SINGLETON_LOCK_VERSION = 1;
|
|
106
|
+
function validateLockRecord(value) {
|
|
107
|
+
if (typeof value !== "object" || value === null || Array.isArray(value)) {
|
|
108
|
+
throw bootstrapFailed("malformed singleton lock record: not an object");
|
|
109
|
+
}
|
|
110
|
+
const record = value;
|
|
111
|
+
if (record.version !== SINGLETON_LOCK_VERSION ||
|
|
112
|
+
typeof record.holderId !== "string" ||
|
|
113
|
+
!Number.isSafeInteger(record.pid) ||
|
|
114
|
+
typeof record.birthToken !== "string" ||
|
|
115
|
+
(record.birthTokenKind !== "native" && record.birthTokenKind !== "opaque") ||
|
|
116
|
+
!Number.isSafeInteger(record.fencingEpoch) ||
|
|
117
|
+
typeof record.endpoint !== "string" ||
|
|
118
|
+
!Number.isSafeInteger(record.acquiredAt)) {
|
|
119
|
+
throw bootstrapFailed("malformed singleton lock record: missing or invalid fields");
|
|
120
|
+
}
|
|
121
|
+
return record;
|
|
122
|
+
}
|
|
123
|
+
function validateClaimRecord(value) {
|
|
124
|
+
if (typeof value !== "object" || value === null || Array.isArray(value)) {
|
|
125
|
+
throw bootstrapFailed("malformed singleton reclaim claim: not an object");
|
|
126
|
+
}
|
|
127
|
+
const record = value;
|
|
128
|
+
if (record.version !== 1 ||
|
|
129
|
+
typeof record.claimantId !== "string" ||
|
|
130
|
+
!Number.isSafeInteger(record.pid) ||
|
|
131
|
+
typeof record.birthToken !== "string" ||
|
|
132
|
+
(record.birthTokenKind !== "native" && record.birthTokenKind !== "opaque") ||
|
|
133
|
+
!Number.isSafeInteger(record.createdAt) ||
|
|
134
|
+
!Number.isSafeInteger(record.targetGeneration)) {
|
|
135
|
+
throw bootstrapFailed("malformed singleton reclaim claim: missing or invalid fields");
|
|
136
|
+
}
|
|
137
|
+
return record;
|
|
138
|
+
}
|
|
139
|
+
// ---------------------------------------------------------------------------
|
|
140
|
+
// Durability primitives (mirror of TE writeJsonAtomicDurable)
|
|
141
|
+
// ---------------------------------------------------------------------------
|
|
142
|
+
function ensurePrivateDirectory(directory) {
|
|
143
|
+
fs.mkdirSync(directory, { recursive: true, mode: 0o700 });
|
|
144
|
+
if (process.platform !== "win32") {
|
|
145
|
+
const stat = fs.statSync(directory);
|
|
146
|
+
if ((stat.mode & 0o077) !== 0)
|
|
147
|
+
fs.chmodSync(directory, 0o700);
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
function fsyncDirectory(directory) {
|
|
151
|
+
try {
|
|
152
|
+
const fd = fs.openSync(directory, "r");
|
|
153
|
+
try {
|
|
154
|
+
fs.fsyncSync(fd);
|
|
155
|
+
}
|
|
156
|
+
finally {
|
|
157
|
+
fs.closeSync(fd);
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
catch { /* best effort */ }
|
|
161
|
+
}
|
|
162
|
+
export function writeJsonAtomicDurable(filePath, value) {
|
|
163
|
+
ensurePrivateDirectory(path.dirname(filePath));
|
|
164
|
+
const temp = `${filePath}.tmp.${process.pid}.${crypto.randomBytes(6).toString("hex")}`;
|
|
165
|
+
const fd = fs.openSync(temp, "wx", 0o600);
|
|
166
|
+
try {
|
|
167
|
+
fs.writeFileSync(fd, JSON.stringify(value));
|
|
168
|
+
fs.fsyncSync(fd);
|
|
169
|
+
}
|
|
170
|
+
finally {
|
|
171
|
+
fs.closeSync(fd);
|
|
172
|
+
}
|
|
173
|
+
try {
|
|
174
|
+
fs.renameSync(temp, filePath);
|
|
175
|
+
fsyncDirectory(path.dirname(filePath));
|
|
176
|
+
}
|
|
177
|
+
catch (error) {
|
|
178
|
+
try {
|
|
179
|
+
fs.unlinkSync(temp);
|
|
180
|
+
}
|
|
181
|
+
catch { /* best effort */ }
|
|
182
|
+
throw error;
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
function readJsonOrNull(filePath) {
|
|
186
|
+
try {
|
|
187
|
+
return JSON.parse(fs.readFileSync(filePath, "utf8"));
|
|
188
|
+
}
|
|
189
|
+
catch (error) {
|
|
190
|
+
if (error.code === "ENOENT")
|
|
191
|
+
return null;
|
|
192
|
+
throw error;
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
function ownerIsDead(record, identity, inspect) {
|
|
196
|
+
return ownerIdentityIsDead(record.pid, record.birthToken, record.birthTokenKind, identity, inspect);
|
|
197
|
+
}
|
|
198
|
+
function ownerIdentityIsDead(pid, birthToken, birthTokenKind, identity, inspect) {
|
|
199
|
+
if (pid === identity.pid) {
|
|
200
|
+
// Opaque tokens identify one module instance, not an OS process. Only
|
|
201
|
+
// native kernel birth tokens are comparable across instances.
|
|
202
|
+
return birthTokenKind === "native" && identity.birthTokenKind === "native" &&
|
|
203
|
+
birthToken !== identity.birthToken;
|
|
204
|
+
}
|
|
205
|
+
const observed = inspect(pid);
|
|
206
|
+
if (!observed.alive)
|
|
207
|
+
return true;
|
|
208
|
+
// Alive but unidentifiable owners are never reclaimed (fail closed).
|
|
209
|
+
if (birthTokenKind !== "native" || observed.birthTokenKind !== "native" || observed.birthToken === undefined)
|
|
210
|
+
return false;
|
|
211
|
+
return observed.birthToken !== birthToken;
|
|
212
|
+
}
|
|
213
|
+
function publishLockByHardLink(lockPath, record) {
|
|
214
|
+
ensurePrivateDirectory(path.dirname(lockPath));
|
|
215
|
+
const temp = `${lockPath}.publish.${process.pid}.${crypto.randomBytes(6).toString("hex")}`;
|
|
216
|
+
const fd = fs.openSync(temp, "wx", 0o600);
|
|
217
|
+
try {
|
|
218
|
+
fs.writeFileSync(fd, JSON.stringify(record));
|
|
219
|
+
fs.fsyncSync(fd);
|
|
220
|
+
}
|
|
221
|
+
finally {
|
|
222
|
+
fs.closeSync(fd);
|
|
223
|
+
}
|
|
224
|
+
try {
|
|
225
|
+
// Hard-link create — never rename-overwrite (P13).
|
|
226
|
+
fs.linkSync(temp, lockPath);
|
|
227
|
+
fs.unlinkSync(temp);
|
|
228
|
+
fsyncDirectory(path.dirname(lockPath));
|
|
229
|
+
}
|
|
230
|
+
catch (error) {
|
|
231
|
+
try {
|
|
232
|
+
fs.unlinkSync(temp);
|
|
233
|
+
}
|
|
234
|
+
catch { /* best effort */ }
|
|
235
|
+
throw error;
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
function readLockRecord(paths) {
|
|
239
|
+
try {
|
|
240
|
+
const value = readJsonOrNull(paths.lockPath);
|
|
241
|
+
return value === null ? null : validateLockRecord(value);
|
|
242
|
+
}
|
|
243
|
+
catch (error) {
|
|
244
|
+
if (error.code === "ENOENT")
|
|
245
|
+
return null;
|
|
246
|
+
throw error;
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
function readLease(paths) {
|
|
250
|
+
try {
|
|
251
|
+
const value = readJsonOrNull(paths.leasePath);
|
|
252
|
+
if (value === null)
|
|
253
|
+
return null;
|
|
254
|
+
return Value.Parse(CoordinatorLeaseSchema, value);
|
|
255
|
+
}
|
|
256
|
+
catch (error) {
|
|
257
|
+
if (error.code === "ENOENT")
|
|
258
|
+
return null;
|
|
259
|
+
throw error;
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
function writeLease(paths, lease) {
|
|
263
|
+
writeJsonAtomicDurable(paths.leasePath, lease);
|
|
264
|
+
}
|
|
265
|
+
/** Monotonic generation survives normal lock/lease cleanup. Only a lock owner
|
|
266
|
+
* publishes this floor, before making its lease usable or deleting its lock. */
|
|
267
|
+
function readEpochFloor(paths) {
|
|
268
|
+
const file = path.join(paths.controlHome, "coordinator-epoch.json");
|
|
269
|
+
try {
|
|
270
|
+
const stat = fs.lstatSync(file);
|
|
271
|
+
if (!stat.isFile() || stat.isSymbolicLink() || process.getuid && stat.uid !== process.getuid() || (stat.mode & 0o077) !== 0)
|
|
272
|
+
throw bootstrapFailed("coordinator epoch file owner, mode or type is invalid");
|
|
273
|
+
const fd = fs.openSync(file, fs.constants.O_RDONLY | fs.constants.O_NOFOLLOW);
|
|
274
|
+
try {
|
|
275
|
+
const opened = fs.fstatSync(fd);
|
|
276
|
+
if (opened.dev !== stat.dev || opened.ino !== stat.ino || opened.size > 1024)
|
|
277
|
+
throw bootstrapFailed("coordinator epoch file identity changed");
|
|
278
|
+
const value = JSON.parse(fs.readFileSync(fd, "utf8"));
|
|
279
|
+
const named = fs.lstatSync(file);
|
|
280
|
+
if (named.dev !== opened.dev || named.ino !== opened.ino)
|
|
281
|
+
throw bootstrapFailed("coordinator epoch file identity changed");
|
|
282
|
+
if (!value || value.version !== 1 || !Number.isSafeInteger(value.fencingEpoch) || value.fencingEpoch < 1 || Object.keys(value).some(key => !["version", "fencingEpoch"].includes(key)))
|
|
283
|
+
throw bootstrapFailed("malformed coordinator epoch floor");
|
|
284
|
+
return value.fencingEpoch;
|
|
285
|
+
}
|
|
286
|
+
finally {
|
|
287
|
+
fs.closeSync(fd);
|
|
288
|
+
}
|
|
289
|
+
}
|
|
290
|
+
catch (error) {
|
|
291
|
+
if (error.code === "ENOENT")
|
|
292
|
+
return readDurableCoordinatorEpoch(path.join(paths.controlHome, "coordinator"));
|
|
293
|
+
if (error instanceof ControlError)
|
|
294
|
+
throw error;
|
|
295
|
+
throw bootstrapFailed("unreadable coordinator epoch floor");
|
|
296
|
+
}
|
|
297
|
+
}
|
|
298
|
+
function persistEpochFloor(paths, epoch) {
|
|
299
|
+
const floor = readEpochFloor(paths);
|
|
300
|
+
if (!Number.isSafeInteger(epoch) || epoch < 1 || epoch < floor)
|
|
301
|
+
throw bootstrapFailed("coordinator epoch cannot move backwards");
|
|
302
|
+
if (epoch !== floor)
|
|
303
|
+
writeJsonAtomicDurable(path.join(paths.controlHome, "coordinator-epoch.json"), { version: 1, fencingEpoch: epoch });
|
|
304
|
+
}
|
|
305
|
+
function claimPath(paths) {
|
|
306
|
+
return `${paths.lockPath}.claim`;
|
|
307
|
+
}
|
|
308
|
+
function discardPath(paths, token) {
|
|
309
|
+
return `${paths.lockPath}.discard.${token}`;
|
|
310
|
+
}
|
|
311
|
+
/** True when the exact lock inode is still ours (compare-and-delete check). */
|
|
312
|
+
function lockInodeMatches(paths, expected) {
|
|
313
|
+
try {
|
|
314
|
+
const stat = fs.statSync(paths.lockPath, { bigint: true });
|
|
315
|
+
return stat.dev === expected.dev && stat.ino === expected.ino;
|
|
316
|
+
}
|
|
317
|
+
catch {
|
|
318
|
+
return false;
|
|
319
|
+
}
|
|
320
|
+
}
|
|
321
|
+
export function acquireUserSingleton(options) {
|
|
322
|
+
const { paths } = options;
|
|
323
|
+
const identity = options.processIdentity ?? defaultProcessIdentity();
|
|
324
|
+
const inspect = options.inspectProcess ?? defaultProcessInspector;
|
|
325
|
+
const now = options.now ?? Date.now;
|
|
326
|
+
const holderId = options.holderId ?? crypto.randomUUID();
|
|
327
|
+
const endpoint = paths.endpointPath;
|
|
328
|
+
const maxAttempts = options.maxAttempts ?? 8;
|
|
329
|
+
const leaseTtlMs = options.leaseTtlMs ?? 30_000;
|
|
330
|
+
ensurePrivateDirectory(paths.controlHome);
|
|
331
|
+
// coordinated (attach-only): the external control must already be alive.
|
|
332
|
+
if (options.attachOnly === true) {
|
|
333
|
+
const existing = readLockRecord(paths);
|
|
334
|
+
if (existing === null || ownerIsDead(existing, identity, inspect)) {
|
|
335
|
+
throw new ControlError("TF_JOURNAL_UNAVAILABLE", "coordinated mode requires an external control which is down; failing closed (P13)", { recoveryAction: "refresh", sideEffects: "none" });
|
|
336
|
+
}
|
|
337
|
+
return {
|
|
338
|
+
status: "attached",
|
|
339
|
+
holderId: existing.holderId,
|
|
340
|
+
fencingEpoch: existing.fencingEpoch,
|
|
341
|
+
endpoint: existing.endpoint,
|
|
342
|
+
};
|
|
343
|
+
}
|
|
344
|
+
let published;
|
|
345
|
+
for (let attempt = 0; attempt < maxAttempts; attempt++) {
|
|
346
|
+
// 1) Try to publish the lock by hard-link create. The durable floor
|
|
347
|
+
// survives graceful shutdown; a fresh install alone starts at one.
|
|
348
|
+
const nextEpoch = readEpochFloor(paths) + 1;
|
|
349
|
+
if (!Number.isSafeInteger(nextEpoch))
|
|
350
|
+
throw bootstrapFailed("coordinator epoch is exhausted");
|
|
351
|
+
const record = {
|
|
352
|
+
version: SINGLETON_LOCK_VERSION,
|
|
353
|
+
holderId,
|
|
354
|
+
pid: identity.pid,
|
|
355
|
+
birthToken: identity.birthToken,
|
|
356
|
+
birthTokenKind: identity.birthTokenKind,
|
|
357
|
+
fencingEpoch: nextEpoch,
|
|
358
|
+
endpoint,
|
|
359
|
+
acquiredAt: now(),
|
|
360
|
+
};
|
|
361
|
+
try {
|
|
362
|
+
publishLockByHardLink(paths.lockPath, record);
|
|
363
|
+
// A previous holder may have completed between our floor read and
|
|
364
|
+
// publication. Retry before exposing a reused generation.
|
|
365
|
+
if (readEpochFloor(paths) >= nextEpoch) {
|
|
366
|
+
fs.unlinkSync(paths.lockPath);
|
|
367
|
+
fsyncDirectory(paths.controlHome);
|
|
368
|
+
continue;
|
|
369
|
+
}
|
|
370
|
+
persistEpochFloor(paths, nextEpoch);
|
|
371
|
+
// 2) Publish the usable lease only after its generation is durable.
|
|
372
|
+
writeLease(paths, {
|
|
373
|
+
holderId,
|
|
374
|
+
fencingEpoch: nextEpoch,
|
|
375
|
+
endpoint,
|
|
376
|
+
expiresAt: now() + leaseTtlMs,
|
|
377
|
+
});
|
|
378
|
+
const stat = fs.statSync(paths.lockPath, { bigint: true });
|
|
379
|
+
published = { dev: stat.dev, ino: stat.ino };
|
|
380
|
+
return {
|
|
381
|
+
status: "won",
|
|
382
|
+
holderId,
|
|
383
|
+
fencingEpoch: nextEpoch,
|
|
384
|
+
endpoint,
|
|
385
|
+
release: () => releaseUserSingleton(paths, { holderId, dev: published.dev, ino: published.ino }),
|
|
386
|
+
};
|
|
387
|
+
}
|
|
388
|
+
catch (error) {
|
|
389
|
+
const code = error.code;
|
|
390
|
+
if (code !== "EEXIST" && code !== "ENOENT" && code !== "EPERM")
|
|
391
|
+
throw error;
|
|
392
|
+
// Lock exists or the publish raced — fall through to inspect/reclaim.
|
|
393
|
+
}
|
|
394
|
+
// 3) Inspect the existing lock record.
|
|
395
|
+
const existing = readLockRecord(paths);
|
|
396
|
+
if (existing === null)
|
|
397
|
+
continue; // vanished between publish and inspect — retry
|
|
398
|
+
// 4) Loser attaches to a live winner (D32) — never run dual authority.
|
|
399
|
+
if (!ownerIsDead(existing, identity, inspect)) {
|
|
400
|
+
return {
|
|
401
|
+
status: "attached",
|
|
402
|
+
holderId: existing.holderId,
|
|
403
|
+
fencingEpoch: existing.fencingEpoch,
|
|
404
|
+
endpoint: existing.endpoint,
|
|
405
|
+
};
|
|
406
|
+
}
|
|
407
|
+
// 5) Identity-bound reclaim of a dead owner (fail-closed).
|
|
408
|
+
const reclaimed = reclaimStaleLock(paths, existing, identity, inspect, now, endpoint, leaseTtlMs, holderId);
|
|
409
|
+
if (reclaimed) {
|
|
410
|
+
const stat = fs.statSync(paths.lockPath, { bigint: true });
|
|
411
|
+
published = { dev: stat.dev, ino: stat.ino };
|
|
412
|
+
return {
|
|
413
|
+
status: "won",
|
|
414
|
+
holderId,
|
|
415
|
+
fencingEpoch: existing.fencingEpoch + 1,
|
|
416
|
+
endpoint,
|
|
417
|
+
release: () => releaseUserSingleton(paths, { holderId, dev: published.dev, ino: published.ino }),
|
|
418
|
+
};
|
|
419
|
+
}
|
|
420
|
+
// Reclaim lost the race or could not be completed; retry with the pass
|
|
421
|
+
// budget (maxAttempts is a hard pass budget — P13).
|
|
422
|
+
}
|
|
423
|
+
throw bootstrapFailed(`could not acquire the user singleton lock after ${maxAttempts} pass(es) (${paths.lockPath})`);
|
|
424
|
+
}
|
|
425
|
+
/**
|
|
426
|
+
* Identity-bound reclaim: fixed claim file + O_EXCL + generation check +
|
|
427
|
+
* rename-to-discard + recoverable claim cleanup.
|
|
428
|
+
*/
|
|
429
|
+
function reclaimStaleLock(paths, existing, identity, inspect, now, endpoint, leaseTtlMs, holderId) {
|
|
430
|
+
const claimFilePath = claimPath(paths);
|
|
431
|
+
const claim = {
|
|
432
|
+
version: 1,
|
|
433
|
+
claimantId: crypto.randomUUID(),
|
|
434
|
+
pid: identity.pid,
|
|
435
|
+
birthToken: identity.birthToken,
|
|
436
|
+
birthTokenKind: identity.birthTokenKind,
|
|
437
|
+
createdAt: now(),
|
|
438
|
+
targetGeneration: existing.acquiredAt,
|
|
439
|
+
};
|
|
440
|
+
// Fixed claim file, O_EXCL create.
|
|
441
|
+
try {
|
|
442
|
+
const fd = fs.openSync(claimFilePath, "wx", 0o600);
|
|
443
|
+
try {
|
|
444
|
+
fs.writeFileSync(fd, JSON.stringify(claim));
|
|
445
|
+
fs.fsyncSync(fd);
|
|
446
|
+
}
|
|
447
|
+
finally {
|
|
448
|
+
fs.closeSync(fd);
|
|
449
|
+
}
|
|
450
|
+
}
|
|
451
|
+
catch (error) {
|
|
452
|
+
if (error.code !== "EEXIST")
|
|
453
|
+
throw error;
|
|
454
|
+
// Another contender holds the claim; recover it if ITS owner is dead.
|
|
455
|
+
let priorRaw = null;
|
|
456
|
+
try {
|
|
457
|
+
priorRaw = readJsonOrNull(claimFilePath);
|
|
458
|
+
}
|
|
459
|
+
catch { /* fall through to fail-closed */ }
|
|
460
|
+
if (priorRaw === null)
|
|
461
|
+
return false;
|
|
462
|
+
let prior;
|
|
463
|
+
try {
|
|
464
|
+
prior = validateClaimRecord(priorRaw);
|
|
465
|
+
}
|
|
466
|
+
catch {
|
|
467
|
+
throw bootstrapFailed("malformed singleton reclaim claim: failing closed");
|
|
468
|
+
}
|
|
469
|
+
if (!ownerIdentityIsDead(prior.pid, prior.birthToken, prior.birthTokenKind, identity, inspect)) {
|
|
470
|
+
return false; // live contender — back off
|
|
471
|
+
}
|
|
472
|
+
fs.unlinkSync(claimFilePath); // recoverable claim cleanup
|
|
473
|
+
return false; // one more pass will retry the whole loop
|
|
474
|
+
}
|
|
475
|
+
try {
|
|
476
|
+
// Generation check: the lock record must still be the one we observed.
|
|
477
|
+
const current = readLockRecord(paths);
|
|
478
|
+
if (current === null || current.holderId !== existing.holderId || current.acquiredAt !== existing.acquiredAt) {
|
|
479
|
+
return false; // another claimant already took over — retry loop
|
|
480
|
+
}
|
|
481
|
+
// Preserve the previous generation before opening the publish gap.
|
|
482
|
+
persistEpochFloor(paths, existing.fencingEpoch);
|
|
483
|
+
if (!Number.isSafeInteger(existing.fencingEpoch + 1))
|
|
484
|
+
throw bootstrapFailed("coordinator epoch is exhausted");
|
|
485
|
+
// rename-to-discard: remove the dead owner's lock without a shared-name
|
|
486
|
+
// ABA window, then publish our own (hard-link create again).
|
|
487
|
+
const discard = discardPath(paths, crypto.randomBytes(8).toString("hex"));
|
|
488
|
+
fs.renameSync(paths.lockPath, discard);
|
|
489
|
+
try {
|
|
490
|
+
fs.unlinkSync(discard);
|
|
491
|
+
}
|
|
492
|
+
catch { /* best effort */ }
|
|
493
|
+
fsyncDirectory(paths.controlHome);
|
|
494
|
+
publishLockByHardLink(paths.lockPath, {
|
|
495
|
+
version: SINGLETON_LOCK_VERSION,
|
|
496
|
+
holderId,
|
|
497
|
+
pid: identity.pid,
|
|
498
|
+
birthToken: identity.birthToken,
|
|
499
|
+
birthTokenKind: identity.birthTokenKind,
|
|
500
|
+
fencingEpoch: existing.fencingEpoch + 1,
|
|
501
|
+
endpoint,
|
|
502
|
+
acquiredAt: now(),
|
|
503
|
+
});
|
|
504
|
+
persistEpochFloor(paths, existing.fencingEpoch + 1);
|
|
505
|
+
writeLease(paths, {
|
|
506
|
+
holderId,
|
|
507
|
+
fencingEpoch: existing.fencingEpoch + 1,
|
|
508
|
+
endpoint,
|
|
509
|
+
expiresAt: now() + leaseTtlMs,
|
|
510
|
+
});
|
|
511
|
+
return true;
|
|
512
|
+
}
|
|
513
|
+
finally {
|
|
514
|
+
try {
|
|
515
|
+
fs.unlinkSync(claimFilePath);
|
|
516
|
+
}
|
|
517
|
+
catch { /* best effort */ }
|
|
518
|
+
}
|
|
519
|
+
}
|
|
520
|
+
/**
|
|
521
|
+
* Release = compare-and-delete on acquire-time device/inode + owner token
|
|
522
|
+
* (P13). rename-to-discard keeps the unlink atomic.
|
|
523
|
+
*/
|
|
524
|
+
export function releaseUserSingleton(paths, acquired) {
|
|
525
|
+
if (!lockInodeMatches(paths, { dev: acquired.dev, ino: acquired.ino }))
|
|
526
|
+
return; // not our lock — never delete someone else's
|
|
527
|
+
const current = readLockRecord(paths);
|
|
528
|
+
if (!current || current.holderId !== acquired.holderId)
|
|
529
|
+
return;
|
|
530
|
+
persistEpochFloor(paths, current.fencingEpoch);
|
|
531
|
+
const discard = discardPath(paths, crypto.randomBytes(8).toString("hex"));
|
|
532
|
+
try {
|
|
533
|
+
fs.renameSync(paths.lockPath, discard);
|
|
534
|
+
fs.unlinkSync(discard);
|
|
535
|
+
fsyncDirectory(paths.controlHome);
|
|
536
|
+
}
|
|
537
|
+
catch {
|
|
538
|
+
// best effort — the lease still gates authority
|
|
539
|
+
}
|
|
540
|
+
try {
|
|
541
|
+
const lease = readLease(paths);
|
|
542
|
+
if (lease !== null && lease.holderId === acquired.holderId)
|
|
543
|
+
fs.unlinkSync(paths.leasePath);
|
|
544
|
+
}
|
|
545
|
+
catch { /* best effort */ }
|
|
546
|
+
}
|
|
547
|
+
/**
|
|
548
|
+
* Fresh-install contract §5.2(4): detect a dead peer (pid/lock), remove its
|
|
549
|
+
* socket file, and let the next acquire restart cleanly. A live owner's
|
|
550
|
+
* endpoint is never touched; malformed metadata fails closed.
|
|
551
|
+
*/
|
|
552
|
+
export function recoverStaleEndpoint(paths, options = {}) {
|
|
553
|
+
if (!fs.existsSync(paths.endpointPath))
|
|
554
|
+
return false;
|
|
555
|
+
const inspect = options.inspectProcess ?? defaultProcessInspector;
|
|
556
|
+
const record = readLockRecord(paths);
|
|
557
|
+
if (record === null) {
|
|
558
|
+
// No lock at all: an orphaned socket is stale by definition.
|
|
559
|
+
try {
|
|
560
|
+
fs.unlinkSync(paths.endpointPath);
|
|
561
|
+
}
|
|
562
|
+
catch { /* best effort */ }
|
|
563
|
+
return true;
|
|
564
|
+
}
|
|
565
|
+
const dead = ownerIsDead(record, defaultProcessIdentity(), inspect);
|
|
566
|
+
if (!dead)
|
|
567
|
+
return false; // live owner — endpoint belongs to it
|
|
568
|
+
try {
|
|
569
|
+
fs.unlinkSync(paths.endpointPath);
|
|
570
|
+
}
|
|
571
|
+
catch { /* best effort */ }
|
|
572
|
+
return true;
|
|
573
|
+
}
|
|
574
|
+
/**
|
|
575
|
+
* Fencing: a client RPC must present a fencingEpoch >= the current lease
|
|
576
|
+
* epoch, or the holder has been fenced out (stale writer) → TF_AUTHORITY_REVOKED.
|
|
577
|
+
* A missing lease means no verifiable authority exists — fail closed rather
|
|
578
|
+
* than accept an unverifiable claim.
|
|
579
|
+
*/
|
|
580
|
+
export function assertFencing(lease, claimedEpoch) {
|
|
581
|
+
if (lease === null) {
|
|
582
|
+
throw new ControlError("TF_AUTHORITY_REVOKED", "no coordinator lease is present; cannot verify fencing authority — failing closed", { recoveryAction: "refresh", sideEffects: "none" });
|
|
583
|
+
}
|
|
584
|
+
if (claimedEpoch < lease.fencingEpoch) {
|
|
585
|
+
throw new ControlError("TF_AUTHORITY_REVOKED", `fencing epoch ${claimedEpoch} is stale; current lease epoch is ${lease.fencingEpoch}`, { recoveryAction: "refresh", sideEffects: "none" });
|
|
586
|
+
}
|
|
587
|
+
}
|
|
588
|
+
/** Read the current CoordinatorLease record (null when none exists). */
|
|
589
|
+
export function readCoordinatorLease(paths) {
|
|
590
|
+
return readLease(paths);
|
|
591
|
+
}
|
|
592
|
+
export function renewCoordinatorLease(paths, holderId, epoch, ttlMs, now) {
|
|
593
|
+
const at = now ?? Date.now;
|
|
594
|
+
const lease = {
|
|
595
|
+
holderId,
|
|
596
|
+
fencingEpoch: epoch,
|
|
597
|
+
endpoint: paths.endpointPath,
|
|
598
|
+
expiresAt: at() + ttlMs,
|
|
599
|
+
};
|
|
600
|
+
const existing = readLease(paths);
|
|
601
|
+
if (existing !== null && existing.holderId !== holderId) {
|
|
602
|
+
throw new ControlError("TF_AUTHORITY_REVOKED", "cannot renew a coordinator lease owned by another holder", { recoveryAction: "refresh", sideEffects: "none" });
|
|
603
|
+
}
|
|
604
|
+
writeLease(paths, lease);
|
|
605
|
+
return lease;
|
|
606
|
+
}
|
|
607
|
+
//# sourceMappingURL=singleton.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"singleton.js","sourceRoot":"","sources":["../../../taskflow-control/src/singleton.ts"],"names":[],"mappings":"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"}
|