@openclaw/crabline 0.1.12 → 0.1.14
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/README.md +38 -11
- package/dist/src/cli/program.js +17 -2
- package/dist/src/cli/program.js.map +1 -1
- package/dist/src/index.d.ts +12 -10
- package/dist/src/index.js +6 -5
- package/dist/src/index.js.map +1 -1
- package/dist/src/openclaw/artifact-generation.d.ts +5 -9
- package/dist/src/openclaw/artifact-generation.js +41 -69
- package/dist/src/openclaw/artifact-generation.js.map +1 -1
- package/dist/src/openclaw/bridges/discord.d.ts +1 -0
- package/dist/src/openclaw/bridges/discord.js +149 -0
- package/dist/src/openclaw/bridges/discord.js.map +1 -0
- package/dist/src/openclaw/bridges/matrix.js +1 -1
- package/dist/src/openclaw/bridges/matrix.js.map +1 -1
- package/dist/src/openclaw/bridges/mattermost.js +1 -1
- package/dist/src/openclaw/bridges/mattermost.js.map +1 -1
- package/dist/src/openclaw/bridges/signal.js +1 -1
- package/dist/src/openclaw/bridges/signal.js.map +1 -1
- package/dist/src/openclaw/bridges/slack.js +1 -1
- package/dist/src/openclaw/bridges/slack.js.map +1 -1
- package/dist/src/openclaw/bridges/telegram.js +1 -1
- package/dist/src/openclaw/bridges/telegram.js.map +1 -1
- package/dist/src/openclaw/bridges/whatsapp.js +1 -1
- package/dist/src/openclaw/bridges/whatsapp.js.map +1 -1
- package/dist/src/openclaw/bridges/zalo.js +1 -1
- package/dist/src/openclaw/bridges/zalo.js.map +1 -1
- package/dist/src/openclaw/outbound-contract.js +3 -0
- package/dist/src/openclaw/outbound-contract.js.map +1 -1
- package/dist/src/openclaw/{smoke-lock.d.ts → provider-readiness-lock.d.ts} +7 -7
- package/dist/src/openclaw/{smoke-lock.js → provider-readiness-lock.js} +122 -260
- package/dist/src/openclaw/provider-readiness-lock.js.map +1 -0
- package/dist/src/openclaw/shared.d.ts +9 -17
- package/dist/src/openclaw/shared.js +5 -6
- package/dist/src/openclaw/shared.js.map +1 -1
- package/dist/src/openclaw.d.ts +3 -5
- package/dist/src/openclaw.js +22 -20
- package/dist/src/openclaw.js.map +1 -1
- package/dist/src/servers/discord.d.ts +40 -0
- package/dist/src/servers/discord.js +842 -0
- package/dist/src/servers/discord.js.map +1 -0
- package/dist/src/servers/index.d.ts +10 -4
- package/dist/src/servers/index.js +4 -0
- package/dist/src/servers/index.js.map +1 -1
- package/dist/src/servers/slack.js +11 -3
- package/dist/src/servers/slack.js.map +1 -1
- package/dist/src/servers/telegram.js +51 -2
- package/dist/src/servers/telegram.js.map +1 -1
- package/dist/src/servers/whatsapp-baileys-websocket.js +7 -0
- package/dist/src/servers/whatsapp-baileys-websocket.js.map +1 -1
- package/dist/src/servers/whatsapp-wire/binary-node.js +12 -0
- package/dist/src/servers/whatsapp-wire/binary-node.js.map +1 -1
- package/dist/src/servers/whatsapp.d.ts +0 -1
- package/dist/src/servers/whatsapp.js +0 -1
- package/dist/src/servers/whatsapp.js.map +1 -1
- package/docs/channel-setup.md +66 -21
- package/package.json +1 -1
- package/dist/src/openclaw/smoke-lock.js.map +0 -1
package/docs/channel-setup.md
CHANGED
|
@@ -4,7 +4,7 @@ Crabline is a local mock service for OpenClaw channel contracts. It has two
|
|
|
4
4
|
surfaces:
|
|
5
5
|
|
|
6
6
|
- fixture-level local mocks used directly by the Crabline CLI
|
|
7
|
-
- local provider servers that OpenClaw
|
|
7
|
+
- local provider servers that real OpenClaw channel plugins can target
|
|
8
8
|
|
|
9
9
|
Live channel testing belongs in OpenClaw's live channel adapters. Crabline
|
|
10
10
|
belongs in deterministic smoke CI and local QA where the test needs
|
|
@@ -224,9 +224,9 @@ watch commands are terminated when cancellation fires.
|
|
|
224
224
|
|
|
225
225
|
## Local Provider Servers
|
|
226
226
|
|
|
227
|
-
Server-backed channels currently include Mattermost, Matrix, Signal,
|
|
228
|
-
Telegram, WhatsApp, and Zalo. Loopback binds retain stable local
|
|
229
|
-
|
|
227
|
+
Server-backed channels currently include Discord, Mattermost, Matrix, Signal,
|
|
228
|
+
Slack, Telegram, WhatsApp, and Zalo. Loopback binds retain stable local
|
|
229
|
+
credentials for deterministic tests. Non-loopback binds generate fresh provider-shaped
|
|
230
230
|
credentials unless the corresponding credential is supplied.
|
|
231
231
|
WhatsApp is loopback-only because its HTTP and WebSocket endpoints carry bearer
|
|
232
232
|
credentials over cleartext and the built-in server does not terminate TLS.
|
|
@@ -264,6 +264,53 @@ to be private. Exclude ready files from version control and CI artifact
|
|
|
264
264
|
collection, and delete them after use. On non-POSIX or shared filesystems,
|
|
265
265
|
verify the effective ACLs before publishing one.
|
|
266
266
|
|
|
267
|
+
### Discord
|
|
268
|
+
|
|
269
|
+
```bash
|
|
270
|
+
crabline --json serve discord --ready-file .crabline/discord-server.json
|
|
271
|
+
```
|
|
272
|
+
|
|
273
|
+
The ready manifest exposes `applicationId`, `botUserId`, `botToken`,
|
|
274
|
+
`endpoints.apiRoot`, `endpoints.gatewayBotUrl`, `endpoints.gatewayUrl`,
|
|
275
|
+
`endpoints.adminInboundUrl`, `adminToken`, and `recorderPath`. OpenClaw-specific
|
|
276
|
+
endpoint injection and target translation belong to the Crabline OpenClaw
|
|
277
|
+
bridge and the OpenClaw Discord plugin; the provider server itself implements
|
|
278
|
+
Discord's public protocol subset and contains no OpenClaw behavior.
|
|
279
|
+
|
|
280
|
+
Post an inbound user message to `endpoints.adminInboundUrl` with the manifest's
|
|
281
|
+
admin token:
|
|
282
|
+
|
|
283
|
+
```json
|
|
284
|
+
{
|
|
285
|
+
"channelId": "135000000000000010",
|
|
286
|
+
"guildId": "135000000000000011",
|
|
287
|
+
"senderId": "135000000000000012",
|
|
288
|
+
"senderName": "Alice",
|
|
289
|
+
"content": "hello"
|
|
290
|
+
}
|
|
291
|
+
```
|
|
292
|
+
|
|
293
|
+
The control plane creates provider state and emits a normal Discord
|
|
294
|
+
`MESSAGE_CREATE` dispatch on an identified Gateway session. `parentChannelId`
|
|
295
|
+
turns `channelId` into a public thread channel. Supported client boundaries are
|
|
296
|
+
REST v10 bot/application identity, Gateway metadata, guild/channel/member
|
|
297
|
+
lookups, DM creation, text message create/read/reply, typing, application
|
|
298
|
+
command registration, and a v10 JSON Gateway with HELLO, IDENTIFY, READY,
|
|
299
|
+
heartbeat acknowledgement, resume, and deterministic shutdown.
|
|
300
|
+
|
|
301
|
+
Current fidelity limits are one Gateway shard, no transport compression, and no
|
|
302
|
+
missed-dispatch replay: resume succeeds only from the retained session's latest
|
|
303
|
+
sequence. The server also omits voice, interaction dispatch,
|
|
304
|
+
attachment/multipart upload, and Discord's distributed permission or
|
|
305
|
+
bucket-allocation systems.
|
|
306
|
+
The server still returns provider-native authentication, JSON error, and basic
|
|
307
|
+
rate-limit headers for its supported routes.
|
|
308
|
+
|
|
309
|
+
This is not the fixture-level Discord local mock. The fixture adapter's
|
|
310
|
+
interactions webhook remains available to Crabline fixture commands; the
|
|
311
|
+
Discord provider server exists so the real OpenClaw Discord plugin can use
|
|
312
|
+
normal REST and Gateway transports without contacting Discord.
|
|
313
|
+
|
|
267
314
|
### Mattermost
|
|
268
315
|
|
|
269
316
|
Start the server:
|
|
@@ -478,7 +525,6 @@ Manifest fields:
|
|
|
478
525
|
- `endpoints.adminInboundUrl`: authenticated admin ingress for test user
|
|
479
526
|
messages using the WhatsApp Business webhook payload shape
|
|
480
527
|
- `endpoints.messagesUrl`: provider-native Cloud API message and status endpoint
|
|
481
|
-
- `endpoints.statusUrl`: alias for the same provider-native status endpoint
|
|
482
528
|
- `recorderPath`: JSONL provider traffic recorder for HTTP traffic and Baileys
|
|
483
529
|
WebSocket stanzas. Multi-message webhook deliveries use one versioned batch
|
|
484
530
|
line that Crabline's recorder APIs flatten into individual events.
|
|
@@ -511,8 +557,8 @@ The admin ingress accepts JSON like:
|
|
|
511
557
|
}
|
|
512
558
|
```
|
|
513
559
|
|
|
514
|
-
Outbound text sends and composing presence are recorded through the
|
|
515
|
-
provider messages and presence endpoints.
|
|
560
|
+
Outbound text sends and composing presence are recorded through the local
|
|
561
|
+
provider server's messages and presence endpoints.
|
|
516
562
|
|
|
517
563
|
### Zalo Server
|
|
518
564
|
|
|
@@ -639,7 +685,7 @@ chat IDs must be negative. Zero is invalid for every Telegram target kind.
|
|
|
639
685
|
|
|
640
686
|
## Smoke CI Guidance
|
|
641
687
|
|
|
642
|
-
For deterministic CI, use Crabline
|
|
688
|
+
For deterministic CI, use the Crabline channel driver:
|
|
643
689
|
|
|
644
690
|
```yaml
|
|
645
691
|
profile: smoke-ci
|
|
@@ -663,8 +709,8 @@ roundtrip. Real OpenClaw channel proof comes from QA scenarios that launch the
|
|
|
663
709
|
gateway and run its normal channel adapter against the local provider.
|
|
664
710
|
|
|
665
711
|
Crabline stages the manifest, capability report, and provider-readiness report
|
|
666
|
-
inside one owner-only generation directory under the
|
|
667
|
-
`.crabline-
|
|
712
|
+
inside one owner-only generation directory under the
|
|
713
|
+
`.crabline-channel-driver-artifacts/` store name, atomically installs the complete
|
|
668
714
|
directory, and then atomically switches the single `current.json` pointer.
|
|
669
715
|
Readers therefore see either the prior complete generation or the next complete
|
|
670
716
|
generation, never per-file mixtures. Setup, probe, cleanup, staging, or
|
|
@@ -687,17 +733,16 @@ contain `capabilityReport` and `providerReadiness` payloads while their manifest
|
|
|
687
733
|
capability, and provider-readiness paths identify the authoritative immutable
|
|
688
734
|
generation.
|
|
689
735
|
|
|
690
|
-
Lock owners
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
and are reclaimed only after their recorded process exits.
|
|
736
|
+
Lock owners use one versioned format containing the PID, process-start identity,
|
|
737
|
+
and token-specific lease. Both the acquisition reservation and owner claim renew
|
|
738
|
+
their 10-minute leases while the readiness run remains active, so a live run
|
|
739
|
+
retains exclusive ownership beyond the initial lease. A heartbeat failure or
|
|
740
|
+
lost ownership aborts publication before the generation is committed. Recovery
|
|
741
|
+
first atomically moves a stale reservation into a uniquely named recovery claim,
|
|
742
|
+
then revalidates its token-specific lease before deletion; a renewal that wins
|
|
743
|
+
the rename race is restored rather than reclaimed. The lease also bounds stale
|
|
744
|
+
locks when an unrelated live process has inherited the abandoned PID. Malformed
|
|
745
|
+
or unversioned owner records fail closed and are not migrated or recovered.
|
|
701
746
|
|
|
702
747
|
For release or live verification, use OpenClaw's live driver:
|
|
703
748
|
|
package/package.json
CHANGED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"smoke-lock.js","sourceRoot":"","sources":["../../../src/openclaw/smoke-lock.ts"],"names":[],"mappings":"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","sourcesContent":["import { randomUUID } from \"node:crypto\";\nimport { spawnSync } from \"node:child_process\";\nimport fsSync, { readFileSync } from \"node:fs\";\nimport fs, { type FileHandle } from \"node:fs/promises\";\nimport path from \"node:path\";\nimport { performance } from \"node:perf_hooks\";\nimport { isCrablineServerChannel, type CrablineServerChannel } from \"../servers/index.js\";\nimport { resolveWindowsPowerShellPath, securePrivateDirectory } from \"./private-file.js\";\nimport { OPENCLAW_CRABLINE_MANIFEST_PATH } from \"./shared.js\";\n\ntype LegacySmokeLockOwner = {\n channel: CrablineServerChannel;\n pid: number;\n token: string;\n};\n\ntype ProcessIdentifiedSmokeLockOwner = LegacySmokeLockOwner & {\n createdAtMs: number;\n processIdentity?: string;\n processIdentityV2?: string;\n processStartedAtMs: number;\n};\n\ntype RenewableSmokeLockOwner = ProcessIdentifiedSmokeLockOwner & {\n leaseVersion: 1;\n};\n\ntype SmokeLockOwner =\n | LegacySmokeLockOwner\n | ProcessIdentifiedSmokeLockOwner\n | RenewableSmokeLockOwner;\n\ntype SmokeLockRecord = {\n owner: SmokeLockOwner;\n renewedAtMs: number;\n};\n\nexport type OpenClawCrablineSmokeRunLock = {\n assertOwned(): Promise<void>;\n commitFileAtomically(params: {\n contents: string;\n destinationPath: string;\n // The directory is an identity fence; temporary contents remain lock-claim-local.\n stageDirectory?: string;\n stageFile(filePath: string, contents: string): Promise<void>;\n }): Promise<void>;\n release(): Promise<void>;\n};\n\ntype HeartbeatController = {\n assertHealthy(): void;\n settle(): Promise<void>;\n stop(): Promise<void>;\n};\ntype RemoveLockDirectory = (lockDirectory: string) => Promise<void>;\ntype Sleep = (delayMs: number) => Promise<void>;\ntype IsProcessAlive = (pid: number) => boolean;\ntype GetProcessIdentity = (pid: number) => string | null;\ntype StartHeartbeat = (renew: () => Promise<void>, intervalMs: number) => HeartbeatController;\ntype BeforeRecoveryClaim = () => Promise<void>;\ntype BeforeRecoveryDeleteClaim = () => Promise<void>;\ntype BeforeCompatibilityMarkerRenew = () => Promise<void>;\ntype BeforeReleaseClaim = () => Promise<void>;\ntype BeforeReleaseRename = () => Promise<void>;\ntype BeforeReleaseRemove = () => Promise<void>;\ntype BeforeCommitClaim = () => Promise<void>;\ntype BeforeCommitFileRename = () => Promise<void>;\ntype BeforeCommitRename = () => Promise<void>;\ntype SecureWindowsDirectory = (directoryPath: string) => Promise<void>;\ntype AfterLockDirectoryWrite = (directoryPath: string) => Promise<void>;\ntype LockClaimKind = \"commit\" | \"owned\" | \"recovering\" | \"release\";\ntype LockClaim = {\n directoryPath: string;\n kind: LockClaimKind;\n};\ntype DirectoryIdentity = {\n device: bigint;\n inode: bigint;\n};\ntype FileIdentity = DirectoryIdentity;\n\ntype SmokeLockRuntime = {\n currentProcessIdentity: string | null;\n currentProcessIdentityV2: string | null;\n currentPid: number;\n currentProcessStartedAtMs: number;\n getProcessIdentity: GetProcessIdentity;\n getProcessIdentityV2: GetProcessIdentity;\n isProcessAlive: IsProcessAlive;\n leaseMs: number;\n now: () => number;\n sleep: Sleep;\n};\n\nconst LOCK_OWNER_FILE = \"owner.json\";\nconst LOCK_LEASE_FILE_PREFIX = \"lease.\";\nconst LOCK_COMMIT_STAGE_FILE_PREFIX = \"commit-stage.\";\nconst LOCK_STAGED_FILE_PREFIX = \".commit-file.\";\nconst LEGACY_RECOVERY_SUFFIX = \".recovering\";\nconst COMMIT_CLAIM_SUFFIX = \".commit\";\nconst OWNED_CLAIM_SUFFIX = \".owned\";\nconst RELEASE_CLAIM_SUFFIX = \".release\";\nconst LOCK_LEASE_MS = 10 * 60 * 1000;\nconst RELEASE_ATTEMPTS = 3;\nconst RELEASE_RETRY_DELAY_MS = 10;\nconst MAX_PROCESS_ID = 2_147_483_647;\nconst CURRENT_PROCESS_STARTED_AT_MS = processStartedAtMsFromTimeOrigin(performance.timeOrigin);\n\nexport function processStartedAtMsFromTimeOrigin(timeOrigin: number): number {\n if (\n !Number.isFinite(timeOrigin) ||\n timeOrigin <= 0 ||\n !Number.isSafeInteger(Math.trunc(timeOrigin))\n ) {\n throw new Error(\"Process time origin is invalid.\");\n }\n return Math.trunc(timeOrigin);\n}\n\nconst sleep: Sleep = async (delayMs) => {\n await new Promise<void>((resolve) => setTimeout(resolve, delayMs));\n};\n\nconst startHeartbeat: StartHeartbeat = (renew, intervalMs) => {\n let failure: unknown;\n let pending: Promise<void> | undefined;\n let stopped = false;\n let timer: NodeJS.Timeout | undefined;\n\n const schedule = () => {\n if (stopped) {\n return;\n }\n timer = setTimeout(() => {\n timer = undefined;\n pending = renew()\n .catch((error: unknown) => {\n failure ??= error;\n })\n .finally(() => {\n pending = undefined;\n schedule();\n });\n }, intervalMs);\n timer.unref();\n };\n\n schedule();\n return {\n assertHealthy() {\n if (failure !== undefined) {\n throw new Error(\"OpenClaw Crabline smoke lock heartbeat failed.\", { cause: failure });\n }\n },\n async settle() {\n await pending;\n },\n async stop() {\n stopped = true;\n if (timer) {\n clearTimeout(timer);\n timer = undefined;\n }\n await pending;\n },\n };\n};\n\nasync function pathExists(filePath: string): Promise<boolean> {\n try {\n await fs.access(filePath);\n return true;\n } catch (error) {\n if (isMissingPathError(error)) {\n return false;\n }\n throw error;\n }\n}\n\nasync function readDirectoryIdentity(directoryPath: string): Promise<DirectoryIdentity | null> {\n try {\n const stats = await fs.lstat(directoryPath, { bigint: true });\n if (!stats.isDirectory() || stats.ino <= 0n) {\n throw new Error(\"OpenClaw Crabline smoke lock claim is not a directory.\");\n }\n return {\n device: stats.dev,\n inode: stats.ino,\n };\n } catch (error) {\n if (isMissingPathError(error)) {\n return null;\n }\n throw error;\n }\n}\n\nasync function readFileIdentity(filePath: string): Promise<FileIdentity | null> {\n try {\n const stats = await fs.lstat(filePath, { bigint: true });\n if (!stats.isFile() || stats.nlink !== 1n || stats.ino <= 0n) {\n return null;\n }\n return {\n device: stats.dev,\n inode: stats.ino,\n };\n } catch (error) {\n if (isMissingPathError(error)) {\n return null;\n }\n throw error;\n }\n}\n\nfunction hasSameDirectoryIdentity(\n left: DirectoryIdentity | null,\n right: DirectoryIdentity | null,\n): boolean {\n return (\n left !== null && right !== null && left.device === right.device && left.inode === right.inode\n );\n}\n\nfunction isOwnedLockArtifactName(name: string, token: string): boolean {\n const leaseName = leaseFileName(token);\n const commitStageName = `${LOCK_COMMIT_STAGE_FILE_PREFIX}${token}.json`;\n return (\n name === LOCK_OWNER_FILE ||\n name === leaseName ||\n (name.startsWith(`.${leaseName}.`) && name.endsWith(\".tmp\")) ||\n name === commitStageName ||\n (name.startsWith(`.${LOCK_COMMIT_STAGE_FILE_PREFIX}${token}.`) && name.endsWith(\".tmp\")) ||\n (name.startsWith(`${LOCK_STAGED_FILE_PREFIX}${token}.`) && name.endsWith(\".tmp\"))\n );\n}\n\nasync function removeVerifiedLockDirectory(params: {\n beforeRemove?: BeforeReleaseRemove;\n directoryPath: string;\n expectedIdentity: DirectoryIdentity;\n token: string;\n}): Promise<void> {\n if (\n !hasSameDirectoryIdentity(\n params.expectedIdentity,\n await readDirectoryIdentity(params.directoryPath),\n )\n ) {\n throw new Error(\"OpenClaw Crabline smoke lock cleanup target changed.\");\n }\n await params.beforeRemove?.();\n const quarantinePath = `${params.directoryPath}.cleanup.${randomUUID()}`;\n fsSync.renameSync(params.directoryPath, quarantinePath);\n let quarantinedIdentity: DirectoryIdentity | null = null;\n const stats = fsSync.lstatSync(quarantinePath, { bigint: true });\n if (stats.isDirectory() && !stats.isSymbolicLink() && stats.ino > 0n) {\n quarantinedIdentity = { device: stats.dev, inode: stats.ino };\n }\n if (!hasSameDirectoryIdentity(params.expectedIdentity, quarantinedIdentity)) {\n throw new Error(\"OpenClaw Crabline smoke lock cleanup target changed.\");\n }\n\n const entries = fsSync.readdirSync(quarantinePath);\n const artifacts: Array<{ identity: FileIdentity; path: string }> = [];\n for (const entry of entries) {\n if (!isOwnedLockArtifactName(entry, params.token)) {\n throw new Error(\"OpenClaw Crabline smoke lock cleanup found an unexpected artifact.\");\n }\n const artifactPath = path.join(quarantinePath, entry);\n const artifactStats = fsSync.lstatSync(artifactPath, { bigint: true });\n if (\n !artifactStats.isFile() ||\n artifactStats.isSymbolicLink() ||\n artifactStats.nlink !== 1n ||\n artifactStats.ino <= 0n\n ) {\n throw new Error(\"OpenClaw Crabline smoke lock cleanup found an unsafe artifact.\");\n }\n artifacts.push({\n identity: { device: artifactStats.dev, inode: artifactStats.ino },\n path: artifactPath,\n });\n }\n artifacts.sort(\n (left, right) =>\n Number(path.basename(left.path) === LOCK_OWNER_FILE) -\n Number(path.basename(right.path) === LOCK_OWNER_FILE),\n );\n for (const artifact of artifacts) {\n const directoryStats = fsSync.lstatSync(quarantinePath, { bigint: true });\n const artifactStats = fsSync.lstatSync(artifact.path, { bigint: true });\n if (\n !directoryStats.isDirectory() ||\n directoryStats.isSymbolicLink() ||\n directoryStats.dev !== params.expectedIdentity.device ||\n directoryStats.ino !== params.expectedIdentity.inode ||\n !artifactStats.isFile() ||\n artifactStats.isSymbolicLink() ||\n artifactStats.nlink !== 1n ||\n artifactStats.dev !== artifact.identity.device ||\n artifactStats.ino !== artifact.identity.inode\n ) {\n throw new Error(\"OpenClaw Crabline smoke lock cleanup artifact changed.\");\n }\n fsSync.unlinkSync(artifact.path);\n }\n const finalStats = fsSync.lstatSync(quarantinePath, { bigint: true });\n if (\n !finalStats.isDirectory() ||\n finalStats.isSymbolicLink() ||\n finalStats.dev !== params.expectedIdentity.device ||\n finalStats.ino !== params.expectedIdentity.inode\n ) {\n throw new Error(\"OpenClaw Crabline smoke lock cleanup target changed.\");\n }\n fsSync.rmdirSync(quarantinePath);\n}\n\nfunction isPositiveSafeInteger(value: unknown): value is number {\n return Number.isSafeInteger(value) && Number(value) > 0;\n}\n\nfunction isValidProcessId(value: unknown): value is number {\n return isPositiveSafeInteger(value) && Number(value) <= MAX_PROCESS_ID;\n}\n\nconst LOCK_TOKEN_PATTERN = /^[A-Za-z0-9][A-Za-z0-9._-]{0,127}$/u;\n\nfunction parseLockOwner(contents: string): SmokeLockOwner {\n let parsed: unknown;\n try {\n parsed = JSON.parse(contents);\n } catch (error) {\n throw new Error(\"OpenClaw Crabline smoke lock owner metadata is malformed.\", {\n cause: error,\n });\n }\n if (!parsed || typeof parsed !== \"object\" || Array.isArray(parsed)) {\n throw new Error(\"OpenClaw Crabline smoke lock owner metadata is malformed.\");\n }\n const owner = parsed as Partial<RenewableSmokeLockOwner>;\n if (\n typeof owner.channel !== \"string\" ||\n !isCrablineServerChannel(owner.channel) ||\n !isValidProcessId(owner.pid) ||\n typeof owner.token !== \"string\" ||\n !LOCK_TOKEN_PATTERN.test(owner.token)\n ) {\n throw new Error(\"OpenClaw Crabline smoke lock owner metadata is malformed.\");\n }\n\n const hasCreatedAt = owner.createdAtMs !== undefined;\n const hasProcessStartedAt = owner.processStartedAtMs !== undefined;\n if (!hasCreatedAt && !hasProcessStartedAt && owner.leaseVersion === undefined) {\n return {\n channel: owner.channel,\n pid: owner.pid,\n token: owner.token,\n };\n }\n if (\n !isPositiveSafeInteger(owner.createdAtMs) ||\n !isPositiveSafeInteger(owner.processStartedAtMs) ||\n (owner.processIdentity !== undefined &&\n (typeof owner.processIdentity !== \"string\" ||\n owner.processIdentity.length === 0 ||\n owner.processIdentity.length > 256)) ||\n (owner.processIdentityV2 !== undefined &&\n (typeof owner.processIdentityV2 !== \"string\" ||\n owner.processIdentityV2.length === 0 ||\n owner.processIdentityV2.length > 256))\n ) {\n throw new Error(\"OpenClaw Crabline smoke lock owner metadata is malformed.\");\n }\n if (owner.leaseVersion === undefined) {\n return {\n channel: owner.channel,\n createdAtMs: owner.createdAtMs,\n pid: owner.pid,\n ...(owner.processIdentity ? { processIdentity: owner.processIdentity } : {}),\n ...(owner.processIdentityV2 ? { processIdentityV2: owner.processIdentityV2 } : {}),\n processStartedAtMs: owner.processStartedAtMs,\n token: owner.token,\n };\n }\n if (owner.leaseVersion !== 1) {\n throw new Error(\"OpenClaw Crabline smoke lock owner metadata is malformed.\");\n }\n return {\n channel: owner.channel,\n createdAtMs: owner.createdAtMs,\n leaseVersion: owner.leaseVersion,\n pid: owner.pid,\n ...(owner.processIdentity ? { processIdentity: owner.processIdentity } : {}),\n ...(owner.processIdentityV2 ? { processIdentityV2: owner.processIdentityV2 } : {}),\n processStartedAtMs: owner.processStartedAtMs,\n token: owner.token,\n };\n}\n\nfunction leaseFileName(token: string): string {\n return `${LOCK_LEASE_FILE_PREFIX}${token}.json`;\n}\n\nasync function readLockRecordFromHandle(handle: FileHandle): Promise<SmokeLockRecord> {\n const owner = parseLockOwner(await handle.readFile(\"utf8\"));\n const stats = await handle.stat();\n return {\n owner,\n renewedAtMs: Number.isFinite(stats.mtimeMs) && stats.mtimeMs > 0 ? stats.mtimeMs : 0,\n };\n}\n\ntype LockRecordReadResult = { kind: \"missing\" } | { kind: \"record\"; record: SmokeLockRecord };\n\nfunction isMissingPathError(error: unknown): boolean {\n return (error as NodeJS.ErrnoException).code === \"ENOENT\";\n}\n\nasync function readLockRecord(lockDirectory: string): Promise<LockRecordReadResult> {\n let handle: FileHandle | undefined;\n try {\n handle = await fs.open(path.join(lockDirectory, LOCK_OWNER_FILE), \"r\");\n const record = await readLockRecordFromHandle(handle);\n if (isRenewableOwner(record.owner)) {\n try {\n const leaseStats = await fs.stat(\n path.join(lockDirectory, leaseFileName(record.owner.token)),\n );\n if (Number.isFinite(leaseStats.mtimeMs) && leaseStats.mtimeMs > 0) {\n record.renewedAtMs = Math.max(record.renewedAtMs, leaseStats.mtimeMs);\n }\n } catch (error) {\n if (!isMissingPathError(error)) {\n throw error;\n }\n }\n }\n return { kind: \"record\", record };\n } catch (error) {\n if (isMissingPathError(error)) {\n return { kind: \"missing\" };\n }\n throw error;\n } finally {\n await handle?.close();\n }\n}\n\nfunction hasProcessIdentity(\n owner: SmokeLockOwner,\n): owner is ProcessIdentifiedSmokeLockOwner | RenewableSmokeLockOwner {\n return \"processStartedAtMs\" in owner;\n}\n\nfunction isRenewableOwner(owner: SmokeLockOwner): owner is RenewableSmokeLockOwner {\n return \"leaseVersion\" in owner && owner.leaseVersion === 1;\n}\n\nexport const isProcessAlive: IsProcessAlive = (pid) => {\n if (!isValidProcessId(pid)) {\n return false;\n }\n try {\n process.kill(pid, 0);\n return true;\n } catch (error) {\n return (error as NodeJS.ErrnoException).code === \"EPERM\";\n }\n};\n\nexport function processIdentityFromLinuxStat(value: string, bootId: string): string | null {\n const normalizedBootId = bootId.trim();\n if (!/^[0-9a-f-]{16,64}$/iu.test(normalizedBootId)) {\n return null;\n }\n const commandEnd = value.lastIndexOf(\") \");\n if (commandEnd < 0) {\n return null;\n }\n const fields = value\n .slice(commandEnd + 2)\n .trim()\n .split(/\\s+/u);\n const startTicks = fields[19];\n if (!startTicks || !/^\\d+$/u.test(startTicks)) {\n return null;\n }\n return `linux:${normalizedBootId}:${startTicks}`;\n}\n\nexport function processIdentityFromDarwin(\n processStartedAt: string,\n bootTime: string,\n): string | null {\n const bootMatch = /\\bsec = (\\d+), usec = (\\d+)\\b/u.exec(bootTime);\n const launchMatch =\n /^Launch Time:\\s*(\\d{4})-(\\d{2})-(\\d{2}) (\\d{2}):(\\d{2}):(\\d{2})\\.(\\d{3,6}) ([+-])(\\d{2})(\\d{2})$/mu.exec(\n processStartedAt,\n );\n if (bootMatch && launchMatch) {\n const [, year, month, day, hour, minute, second, fraction, sign, offsetHour, offsetMinute] =\n launchMatch as RegExpExecArray &\n [string, string, string, string, string, string, string, string, string, string, string];\n const offsetMs =\n (Number(offsetHour) * 60 + Number(offsetMinute)) * 60_000 * (sign === \"+\" ? 1 : -1);\n const fractionMicros = Number(fraction.padEnd(6, \"0\"));\n const utcMilliseconds =\n Date.UTC(\n Number(year),\n Number(month) - 1,\n Number(day),\n Number(hour),\n Number(minute),\n Number(second),\n Math.floor(fractionMicros / 1_000),\n ) - offsetMs;\n if (Number.isSafeInteger(utcMilliseconds) && utcMilliseconds > 0) {\n const startedAtMicros = BigInt(utcMilliseconds) * 1_000n + BigInt(fractionMicros % 1_000);\n return `darwin:${bootMatch[1]}.${bootMatch[2]}:us:${startedAtMicros}`;\n }\n }\n const normalizedStartedAt = processStartedAt.trim().replace(/\\s+/gu, \" \");\n if (!bootMatch || normalizedStartedAt.length === 0 || normalizedStartedAt.length > 64) {\n return null;\n }\n return `darwin:${bootMatch[1]}.${bootMatch[2]}:${normalizedStartedAt}`;\n}\n\nexport function darwinProcessIdentityEnvironment(\n environment: NodeJS.ProcessEnv,\n): NodeJS.ProcessEnv {\n return { ...environment, LC_ALL: \"C\", TZ: \"UTC\" };\n}\n\nconst getProcessIdentity: GetProcessIdentity = (pid) => {\n if (process.platform === \"linux\") {\n try {\n return processIdentityFromLinuxStat(\n readFileSync(`/proc/${pid}/stat`, \"utf8\"),\n readFileSync(\"/proc/sys/kernel/random/boot_id\", \"utf8\"),\n );\n } catch {\n return null;\n }\n }\n if (process.platform === \"darwin\") {\n const options = {\n encoding: \"utf8\" as const,\n env: darwinProcessIdentityEnvironment(process.env),\n maxBuffer: 512 * 1024,\n timeout: 1_000,\n };\n const bootTime = spawnSync(\"/usr/sbin/sysctl\", [\"-n\", \"kern.boottime\"], options);\n if (bootTime.status !== 0) {\n return null;\n }\n const startedAt = spawnSync(\"/bin/ps\", [\"-o\", \"lstart=\", \"-p\", String(pid)], options);\n return startedAt.status === 0\n ? processIdentityFromDarwin(startedAt.stdout, bootTime.stdout)\n : null;\n }\n if (process.platform !== \"win32\") {\n return null;\n }\n let powershellPath: string;\n try {\n powershellPath = resolveWindowsPowerShellPath(process.env.SystemRoot);\n } catch {\n return null;\n }\n const result = spawnSync(\n powershellPath,\n [\n \"-NoProfile\",\n \"-NonInteractive\",\n \"-Command\",\n `(Get-Process -Id ${pid} -ErrorAction Stop).StartTime.ToUniversalTime().Ticks.ToString()`,\n ],\n { encoding: \"utf8\", timeout: 1_000, windowsHide: true },\n );\n const ticks = result.status === 0 ? result.stdout.trim() : \"\";\n return /^\\d+$/u.test(ticks) ? `windows:${ticks}` : null;\n};\n\nconst getProcessIdentityV2: GetProcessIdentity = (pid) => {\n if (process.platform !== \"darwin\") {\n return null;\n }\n const options = {\n encoding: \"utf8\" as const,\n env: darwinProcessIdentityEnvironment(process.env),\n maxBuffer: 512 * 1024,\n timeout: 3_000,\n };\n const bootTime = spawnSync(\"/usr/sbin/sysctl\", [\"-n\", \"kern.boottime\"], options);\n const processDetails = spawnSync(\"/usr/bin/vmmap\", [\"-summary\", String(pid)], options);\n if (bootTime.status !== 0 || processDetails.status !== 0) {\n return null;\n }\n const identity = processIdentityFromDarwin(processDetails.stdout, bootTime.stdout);\n return identity?.includes(\":us:\") ? identity : null;\n};\n\nlet cachedCurrentProcessIdentity: string | null = null;\nlet cachedCurrentProcessIdentityV2: string | null = null;\n\nfunction getCachedCurrentProcessIdentity(): string | null {\n return (cachedCurrentProcessIdentity ??= getProcessIdentity(process.pid));\n}\n\nfunction getCachedCurrentProcessIdentityV2(): string | null {\n return (cachedCurrentProcessIdentityV2 ??= getProcessIdentityV2(process.pid));\n}\n\nfunction hasExactProcessIdentity(owner: SmokeLockOwner): owner is (\n | ProcessIdentifiedSmokeLockOwner\n | RenewableSmokeLockOwner\n) & {\n processIdentity: string;\n} {\n return hasProcessIdentity(owner) && typeof owner.processIdentity === \"string\";\n}\n\nfunction hasCoarseDarwinProcessIdentity(owner: SmokeLockOwner): owner is (\n | ProcessIdentifiedSmokeLockOwner\n | RenewableSmokeLockOwner\n) & {\n processIdentity: string;\n} {\n if (!hasExactProcessIdentity(owner)) {\n return false;\n }\n return /^darwin:\\d+\\.\\d+:(?!us:).+$/u.test(owner.processIdentity);\n}\n\ntype ProcessIdentityMatch = \"legacy\" | \"mismatch\" | \"unknown\" | \"v2\";\n\nfunction compareProcessIdentity(\n owner: SmokeLockOwner,\n runtime: SmokeLockRuntime,\n): ProcessIdentityMatch {\n if (\n hasProcessIdentity(owner) &&\n owner.pid === runtime.currentPid &&\n owner.processStartedAtMs !== runtime.currentProcessStartedAtMs\n ) {\n return \"mismatch\";\n }\n if (!hasExactProcessIdentity(owner)) {\n return \"unknown\";\n }\n if (hasProcessIdentity(owner) && typeof owner.processIdentityV2 === \"string\") {\n const actualProcessIdentityV2 =\n owner.pid === runtime.currentPid\n ? runtime.currentProcessIdentityV2\n : runtime.getProcessIdentityV2(owner.pid);\n if (actualProcessIdentityV2 !== null) {\n return owner.processIdentityV2 === actualProcessIdentityV2 ? \"v2\" : \"mismatch\";\n }\n }\n const actualProcessIdentity =\n owner.pid === runtime.currentPid\n ? runtime.currentProcessIdentity\n : runtime.getProcessIdentity(owner.pid);\n if (actualProcessIdentity === null) {\n return \"unknown\";\n }\n return owner.processIdentity === actualProcessIdentity ? \"legacy\" : \"mismatch\";\n}\n\nfunction hasProcessIdentityMismatch(owner: SmokeLockOwner, runtime: SmokeLockRuntime): boolean {\n return compareProcessIdentity(owner, runtime) === \"mismatch\";\n}\n\nfunction isLockOwnerActive(record: SmokeLockRecord, runtime: SmokeLockRuntime): boolean {\n const { owner } = record;\n if (!runtime.isProcessAlive(owner.pid)) {\n return false;\n }\n const identityMatch = compareProcessIdentity(owner, runtime);\n if (identityMatch === \"mismatch\") {\n return false;\n }\n if (!isRenewableOwner(owner)) {\n if (\n owner.pid !== runtime.currentPid &&\n hasCoarseDarwinProcessIdentity(owner) &&\n identityMatch !== \"v2\"\n ) {\n const ageMs = runtime.now() - Math.max(owner.createdAtMs, record.renewedAtMs);\n return ageMs >= -runtime.leaseMs && ageMs <= runtime.leaseMs;\n }\n return true;\n }\n const ageMs = runtime.now() - Math.max(owner.createdAtMs, record.renewedAtMs);\n return ageMs >= -runtime.leaseMs && ageMs <= runtime.leaseMs;\n}\n\nfunction needsLiveOwnerConfirmation(record: SmokeLockRecord, runtime: SmokeLockRuntime): boolean {\n return (\n isRenewableOwner(record.owner) &&\n runtime.isProcessAlive(record.owner.pid) &&\n !hasProcessIdentityMismatch(record.owner, runtime) &&\n !isLockOwnerActive(record, runtime)\n );\n}\n\ntype OwnerConfirmation = \"changed\" | \"renewed\" | \"unchanged\";\n\nfunction heartbeatIntervalMs(leaseMs: number): number {\n return Math.max(1, Math.floor(leaseMs / 3));\n}\n\nasync function confirmObservedOwner(\n lockDirectory: string,\n observed: SmokeLockRecord,\n runtime: SmokeLockRuntime,\n): Promise<OwnerConfirmation> {\n if (!needsLiveOwnerConfirmation(observed, runtime)) {\n return \"unchanged\";\n }\n await runtime.sleep(heartbeatIntervalMs(runtime.leaseMs));\n const revalidated = await readLockRecord(lockDirectory);\n if (revalidated.kind !== \"record\") {\n return \"unchanged\";\n }\n if (revalidated.record.owner.token !== observed.owner.token) {\n return \"changed\";\n }\n return revalidated.record.renewedAtMs !== observed.renewedAtMs ||\n isLockOwnerActive(revalidated.record, runtime)\n ? \"renewed\"\n : \"unchanged\";\n}\n\nfunction activeRunError(params: {\n cause?: unknown;\n channel?: CrablineServerChannel;\n outputDir: string;\n requestedChannel: CrablineServerChannel;\n}): Error {\n return new Error(\n `OpenClaw Crabline smoke is already running for channel \"${params.channel ?? \"unknown\"}\" in \"${params.outputDir}\"; cannot start channel \"${params.requestedChannel}\".`,\n params.cause === undefined ? undefined : { cause: params.cause },\n );\n}\n\nfunction isPathConfinedTo(rootPath: string, candidatePath: string): boolean {\n const relative = path.relative(rootPath, candidatePath);\n return (\n relative === \"\" ||\n (!path.isAbsolute(relative) && relative !== \"..\" && !relative.startsWith(`..${path.sep}`))\n );\n}\n\nasync function resolveConfinedPath(\n rootPath: string,\n candidatePath: string,\n description: string,\n candidateKind: \"directory\" | \"file\",\n): Promise<string> {\n const resolvedPath = path.resolve(candidatePath);\n if (resolvedPath !== candidatePath) {\n throw new Error(`OpenClaw Crabline smoke lock ${description} escapes its output directory.`);\n }\n const parentPath = candidateKind === \"directory\" ? resolvedPath : path.dirname(resolvedPath);\n let realParentPath: string;\n try {\n realParentPath = await fs.realpath(parentPath);\n } catch {\n throw new Error(`OpenClaw Crabline smoke lock ${description} is invalid.`);\n }\n if (!isPathConfinedTo(rootPath, realParentPath)) {\n throw new Error(`OpenClaw Crabline smoke lock ${description} escapes its output directory.`);\n }\n return candidateKind === \"directory\"\n ? realParentPath\n : path.join(realParentPath, path.basename(resolvedPath));\n}\n\nasync function removeOwnedLock(params: {\n beforeClaim?: () => Promise<void>;\n beforeRename?: () => Promise<void>;\n beforeRemove?: BeforeReleaseRemove;\n lockDirectory: string;\n onOwnedDirectoryChange?: (directoryPath: string) => void;\n ownedDirectory: string;\n removeDirectory?: RemoveLockDirectory;\n runtime?: SmokeLockRuntime;\n token: string;\n}): Promise<boolean> {\n await params.beforeClaim?.();\n const observed = await readLockRecord(params.ownedDirectory);\n if (observed.kind === \"missing\" || observed.record.owner.token !== params.token) {\n return false;\n }\n const observedIdentity = await readDirectoryIdentity(params.ownedDirectory);\n if (observedIdentity === null) {\n return false;\n }\n const revalidated = await readLockRecord(params.ownedDirectory);\n const revalidatedIdentity = await readDirectoryIdentity(params.ownedDirectory);\n if (\n revalidated.kind === \"missing\" ||\n revalidated.record.owner.token !== params.token ||\n !hasSameDirectoryIdentity(observedIdentity, revalidatedIdentity) ||\n (params.runtime !== undefined && isLockOwnerActive(revalidated.record, params.runtime))\n ) {\n return false;\n }\n\n await params.beforeRename?.();\n const releaseClaim = `${params.lockDirectory}${RELEASE_CLAIM_SUFFIX}.${params.token}.${randomUUID()}`;\n try {\n await fs.rename(params.ownedDirectory, releaseClaim);\n } catch (error) {\n if (isMissingPathError(error)) {\n return false;\n }\n throw error;\n }\n params.onOwnedDirectoryChange?.(releaseClaim);\n\n const claimed = await readLockRecord(releaseClaim);\n const claimedIdentity = await readDirectoryIdentity(releaseClaim);\n if (\n claimed.kind === \"missing\" ||\n claimed.record.owner.token !== params.token ||\n !hasSameDirectoryIdentity(observedIdentity, claimedIdentity) ||\n (params.runtime !== undefined && isLockOwnerActive(claimed.record, params.runtime))\n ) {\n if (!(await pathExists(params.ownedDirectory))) {\n try {\n await fs.rename(releaseClaim, params.ownedDirectory);\n params.onOwnedDirectoryChange?.(params.ownedDirectory);\n } catch (error) {\n if (!isMissingPathError(error)) {\n throw error;\n }\n }\n }\n return false;\n }\n\n if (params.removeDirectory) {\n await params.removeDirectory(releaseClaim);\n } else {\n await removeVerifiedLockDirectory({\n ...(params.beforeRemove ? { beforeRemove: params.beforeRemove } : {}),\n directoryPath: releaseClaim,\n expectedIdentity: observedIdentity,\n token: params.token,\n });\n }\n return true;\n}\n\nasync function renewCompatibilityMarker(params: {\n handle: FileHandle;\n lockDirectory: string;\n renewedAtMs: number;\n securedDirectory: Awaited<ReturnType<typeof securePrivateDirectory>>;\n token: string;\n}): Promise<boolean> {\n await params.securedDirectory.assertIdentityAt(params.lockDirectory);\n const observed = await readLockRecord(params.lockDirectory);\n if (observed.kind === \"missing\" || observed.record.owner.token !== params.token) {\n return false;\n }\n const renewedAt = new Date(params.renewedAtMs);\n await params.handle.utimes(renewedAt, renewedAt);\n await params.handle.sync();\n await params.securedDirectory.assertIdentityAt(params.lockDirectory);\n const revalidated = await readLockRecord(params.lockDirectory);\n return revalidated.kind === \"record\" && revalidated.record.owner.token === params.token;\n}\n\nasync function assertCompatibilityMarkerOwned(params: {\n lockDirectory: string;\n securedDirectory: Awaited<ReturnType<typeof securePrivateDirectory>>;\n token: string;\n}): Promise<void> {\n await params.securedDirectory.assertIdentityAt(params.lockDirectory);\n const observed = await readLockRecord(params.lockDirectory);\n if (observed.kind === \"missing\" || observed.record.owner.token !== params.token) {\n throw new Error(\"OpenClaw Crabline smoke lock compatibility marker was lost.\");\n }\n}\n\nasync function retireCompatibilityMarker(\n handle: FileHandle,\n owner: RenewableSmokeLockOwner,\n): Promise<void> {\n const retiredOwner: RenewableSmokeLockOwner = {\n ...owner,\n createdAtMs: 1,\n pid: MAX_PROCESS_ID,\n ...(owner.processIdentity ? { processIdentity: \"retired\" } : {}),\n ...(owner.processIdentityV2 ? { processIdentityV2: \"retired\" } : {}),\n processStartedAtMs: 1,\n };\n const originalBytes = Buffer.byteLength(`${JSON.stringify(owner)}\\n`, \"utf8\");\n const retiredJson = JSON.stringify(retiredOwner);\n const retiredBytes = Buffer.byteLength(retiredJson, \"utf8\") + 1;\n const targetBytes = Math.max(originalBytes, retiredBytes);\n const paddingBytes = targetBytes - retiredBytes;\n const retiredContents = `${retiredJson}${\" \".repeat(paddingBytes)}\\n`;\n const written = await handle.write(retiredContents, 0, \"utf8\");\n if (written.bytesWritten !== targetBytes) {\n throw new Error(\"OpenClaw Crabline smoke lock compatibility marker retirement was incomplete.\");\n }\n const retiredAt = new Date(1);\n await handle.utimes(retiredAt, retiredAt);\n await handle.sync();\n}\n\nasync function renewOwnedLock(\n lockDirectory: string,\n token: string,\n renewedAtMs: number,\n): Promise<boolean> {\n const temporaryLeasePath = path.join(\n lockDirectory,\n `.${leaseFileName(token)}.${randomUUID()}.tmp`,\n );\n try {\n const observed = await readLockRecord(lockDirectory);\n if (\n observed.kind === \"missing\" ||\n observed.record.owner.token !== token ||\n !isRenewableOwner(observed.record.owner)\n ) {\n return false;\n }\n await fs.writeFile(temporaryLeasePath, `${JSON.stringify({ renewedAtMs, token })}\\n`, {\n encoding: \"utf8\",\n flag: \"wx\",\n mode: 0o600,\n });\n await fs.chmod(temporaryLeasePath, 0o600);\n const renewedAt = new Date(renewedAtMs);\n await fs.utimes(temporaryLeasePath, renewedAt, renewedAt);\n const revalidated = await readLockRecord(lockDirectory);\n if (\n revalidated.kind === \"missing\" ||\n revalidated.record.owner.token !== token ||\n !isRenewableOwner(revalidated.record.owner)\n ) {\n return false;\n }\n await fs.rename(temporaryLeasePath, path.join(lockDirectory, leaseFileName(token)));\n return true;\n } catch (error) {\n if (isMissingPathError(error)) {\n return false;\n }\n throw error;\n } finally {\n await fs.rm(temporaryLeasePath, { force: true }).catch(() => undefined);\n }\n}\n\nfunction claimPrefix(lockDirectory: string, suffix: string): string {\n return `${path.basename(lockDirectory)}${suffix}.`;\n}\n\nasync function listLockClaims(lockDirectory: string): Promise<LockClaim[]> {\n const directory = path.dirname(lockDirectory);\n const prefixes: Array<{ kind: LockClaimKind; prefix: string }> = [\n { kind: \"recovering\", prefix: claimPrefix(lockDirectory, LEGACY_RECOVERY_SUFFIX) },\n { kind: \"commit\", prefix: claimPrefix(lockDirectory, COMMIT_CLAIM_SUFFIX) },\n { kind: \"owned\", prefix: claimPrefix(lockDirectory, OWNED_CLAIM_SUFFIX) },\n { kind: \"release\", prefix: claimPrefix(lockDirectory, RELEASE_CLAIM_SUFFIX) },\n ];\n const entries = await fs.readdir(directory, { withFileTypes: true });\n const claims: LockClaim[] = [];\n for (const entry of entries) {\n const match = prefixes.find(({ prefix }) => entry.name.startsWith(prefix));\n if (!match) {\n continue;\n }\n if (!entry.isDirectory()) {\n throw new Error(\"OpenClaw Crabline smoke lock claim is not a directory.\");\n }\n claims.push({\n directoryPath: path.join(directory, entry.name),\n kind: match.kind,\n });\n }\n return claims.sort((left, right) => left.directoryPath.localeCompare(right.directoryPath));\n}\n\nasync function claimLegacyRecoveryDirectory(\n lockDirectory: string,\n expectedToken?: string,\n): Promise<void> {\n const legacyRecoveryDirectory = `${lockDirectory}${LEGACY_RECOVERY_SUFFIX}`;\n if (!(await pathExists(legacyRecoveryDirectory))) {\n return;\n }\n if (expectedToken !== undefined) {\n const observed = await readLockRecord(legacyRecoveryDirectory);\n if (observed.kind === \"missing\" || observed.record.owner.token !== expectedToken) {\n return;\n }\n }\n try {\n await fs.rename(\n legacyRecoveryDirectory,\n `${lockDirectory}${LEGACY_RECOVERY_SUFFIX}.${randomUUID()}`,\n );\n } catch (error) {\n if (!isMissingPathError(error)) {\n throw error;\n }\n }\n}\n\nasync function resolveLockClaim(params: {\n beforeRecoveryDeleteClaim: BeforeRecoveryDeleteClaim;\n claim: LockClaim;\n lockDirectory: string;\n outputDir: string;\n requestedChannel: CrablineServerChannel;\n runtime: SmokeLockRuntime;\n}): Promise<void> {\n const observed = await readLockRecord(params.claim.directoryPath);\n if (observed.kind === \"missing\") {\n const discardDirectory = `${params.lockDirectory}.discard.${randomUUID()}`;\n try {\n await fs.rename(params.claim.directoryPath, discardDirectory);\n } catch (error) {\n if (isMissingPathError(error)) {\n return;\n }\n throw error;\n }\n const claimed = await readLockRecord(discardDirectory);\n if (claimed.kind === \"record\") {\n await fs.rename(discardDirectory, params.claim.directoryPath);\n await resolveLockClaim(params);\n return;\n }\n await fs.rm(discardDirectory, { force: true, recursive: true });\n return;\n }\n if (isLockOwnerActive(observed.record, params.runtime)) {\n if (params.claim.kind === \"recovering\") {\n try {\n await fs.rename(params.claim.directoryPath, params.lockDirectory);\n } catch (error) {\n if (!(await pathExists(params.lockDirectory))) {\n throw error;\n }\n }\n }\n throw activeRunError({\n channel: observed.record.owner.channel,\n outputDir: params.outputDir,\n requestedChannel: params.requestedChannel,\n });\n }\n const confirmation = await confirmObservedOwner(\n params.claim.directoryPath,\n observed.record,\n params.runtime,\n );\n if (confirmation === \"renewed\") {\n if (params.claim.kind === \"recovering\") {\n try {\n await fs.rename(params.claim.directoryPath, params.lockDirectory);\n } catch (error) {\n if (!(await pathExists(params.lockDirectory))) {\n throw error;\n }\n }\n }\n throw activeRunError({\n channel: observed.record.owner.channel,\n outputDir: params.outputDir,\n requestedChannel: params.requestedChannel,\n });\n }\n if (confirmation === \"changed\") {\n await resolveLockClaim(params);\n return;\n }\n\n const revalidated = await readLockRecord(params.claim.directoryPath);\n if (revalidated.kind === \"missing\") {\n await resolveLockClaim(params);\n return;\n }\n if (\n revalidated.record.owner.token !== observed.record.owner.token ||\n isLockOwnerActive(revalidated.record, params.runtime)\n ) {\n await resolveLockClaim(params);\n return;\n }\n if (\n !(await removeOwnedLock({\n beforeClaim: params.beforeRecoveryDeleteClaim,\n lockDirectory: params.lockDirectory,\n ownedDirectory: params.claim.directoryPath,\n runtime: params.runtime,\n token: revalidated.record.owner.token,\n }))\n ) {\n await resolveLockClaim(params);\n }\n}\n\nasync function resolveLockClaims(params: {\n beforeRecoveryDeleteClaim: BeforeRecoveryDeleteClaim;\n lockDirectory: string;\n outputDir: string;\n requestedChannel: CrablineServerChannel;\n runtime: SmokeLockRuntime;\n}): Promise<void> {\n await claimLegacyRecoveryDirectory(params.lockDirectory);\n for (const claim of await listLockClaims(params.lockDirectory)) {\n await resolveLockClaim({\n ...params,\n claim,\n });\n }\n}\n\nasync function resolveLockContention(params: {\n beforeRecoveryDeleteClaim: BeforeRecoveryDeleteClaim;\n cause: unknown;\n lockDirectory: string;\n outputDir: string;\n requestedChannel: CrablineServerChannel;\n runtime: SmokeLockRuntime;\n beforeRecoveryClaim: BeforeRecoveryClaim;\n}): Promise<void> {\n const observed = await readLockRecord(params.lockDirectory);\n if (observed.kind === \"record\" && isLockOwnerActive(observed.record, params.runtime)) {\n throw activeRunError({\n cause: params.cause,\n channel: observed.record.owner.channel,\n outputDir: params.outputDir,\n requestedChannel: params.requestedChannel,\n });\n }\n if (observed.kind === \"record\") {\n const confirmation = await confirmObservedOwner(\n params.lockDirectory,\n observed.record,\n params.runtime,\n );\n if (confirmation === \"renewed\") {\n throw activeRunError({\n channel: observed.record.owner.channel,\n outputDir: params.outputDir,\n requestedChannel: params.requestedChannel,\n });\n }\n if (confirmation === \"changed\") {\n await resolveLockContention(params);\n return;\n }\n }\n\n await params.beforeRecoveryClaim();\n const claimDirectory = `${params.lockDirectory}${LEGACY_RECOVERY_SUFFIX}.${randomUUID()}`;\n try {\n await fs.rename(params.lockDirectory, claimDirectory);\n } catch (error) {\n if (!(await pathExists(params.lockDirectory))) {\n await resolveLockClaims(params);\n return;\n }\n throw error;\n }\n\n await resolveLockClaim({\n ...params,\n claim: {\n directoryPath: claimDirectory,\n kind: \"recovering\",\n },\n });\n}\n\nasync function createLockCandidate(params: {\n afterOwnerWrite?: AfterLockDirectoryWrite;\n candidateDirectory?: string;\n includeLease?: boolean;\n lockDirectory: string;\n owner: RenewableSmokeLockOwner;\n platform?: NodeJS.Platform;\n secureWindowsDirectory?: SecureWindowsDirectory;\n}): Promise<{\n candidateDirectory: string;\n securedDirectory: Awaited<ReturnType<typeof securePrivateDirectory>>;\n}> {\n const candidateDirectory =\n params.candidateDirectory ??\n `${params.lockDirectory}.${params.owner.pid}.${params.owner.token}.tmp`;\n await fs.mkdir(candidateDirectory, { mode: 0o700 });\n try {\n const securedDirectory = await securePrivateDirectory(candidateDirectory, {\n ...(params.platform ? { platform: params.platform } : {}),\n ...(params.secureWindowsDirectory\n ? { secureWindowsDirectory: params.secureWindowsDirectory }\n : {}),\n });\n await securedDirectory.assertIdentityAt();\n const ownerPath = path.join(candidateDirectory, LOCK_OWNER_FILE);\n await fs.writeFile(ownerPath, `${JSON.stringify(params.owner)}\\n`, {\n encoding: \"utf8\",\n flag: \"wx\",\n mode: 0o600,\n });\n await fs.chmod(ownerPath, 0o600);\n const createdAt = new Date(params.owner.createdAtMs);\n await fs.utimes(ownerPath, createdAt, createdAt);\n await params.afterOwnerWrite?.(candidateDirectory);\n await securedDirectory.assertIdentityAt();\n\n if (params.includeLease !== false) {\n const leasePath = path.join(candidateDirectory, leaseFileName(params.owner.token));\n await fs.writeFile(\n leasePath,\n `${JSON.stringify({ renewedAtMs: params.owner.createdAtMs, token: params.owner.token })}\\n`,\n {\n encoding: \"utf8\",\n flag: \"wx\",\n mode: 0o600,\n },\n );\n await fs.chmod(leasePath, 0o600);\n await fs.utimes(leasePath, createdAt, createdAt);\n }\n await securedDirectory.assertIdentityAt();\n return { candidateDirectory, securedDirectory };\n } catch (error) {\n await fs.rm(candidateDirectory, { force: true, recursive: true }).catch(() => undefined);\n throw error;\n }\n}\n\nexport async function acquireOpenClawCrablineSmokeRunLock(\n params: {\n channel: CrablineServerChannel;\n outputDir: string;\n },\n dependencies: {\n afterLockCandidateInstall?: AfterLockDirectoryWrite;\n afterLockOwnerClaimInstall?: AfterLockDirectoryWrite;\n afterLockOwnerWrite?: AfterLockDirectoryWrite;\n getProcessIdentity?: GetProcessIdentity;\n getProcessIdentityV2?: GetProcessIdentity;\n isProcessAlive?: IsProcessAlive;\n leaseMs?: number;\n now?: () => number;\n pid?: number;\n processIdentity?: string | null;\n processIdentityV2?: string | null;\n processStartedAtMs?: number;\n platform?: NodeJS.Platform;\n secureWindowsDirectory?: SecureWindowsDirectory;\n beforeCommitClaim?: BeforeCommitClaim;\n beforeCommitFileRename?: BeforeCommitFileRename;\n beforeCommitRename?: BeforeCommitRename;\n beforeCompatibilityMarkerRenew?: BeforeCompatibilityMarkerRenew;\n beforeRecoveryDeleteClaim?: BeforeRecoveryDeleteClaim;\n beforeRecoveryClaim?: BeforeRecoveryClaim;\n beforeReleaseClaim?: BeforeReleaseClaim;\n beforeReleaseRename?: BeforeReleaseRename;\n beforeReleaseRemove?: BeforeReleaseRemove;\n removeDirectory?: RemoveLockDirectory;\n sleep?: Sleep;\n startHeartbeat?: StartHeartbeat;\n } = {},\n): Promise<OpenClawCrablineSmokeRunLock> {\n const requestedOutputDir = path.resolve(params.outputDir);\n await fs.mkdir(requestedOutputDir, { recursive: true });\n const outputDir = await fs.realpath(requestedOutputDir);\n const privateDirectoryOptions = {\n ...(dependencies.platform ? { platform: dependencies.platform } : {}),\n ...(dependencies.secureWindowsDirectory\n ? { secureWindowsDirectory: dependencies.secureWindowsDirectory }\n : {}),\n };\n const securedOutputDirectory = await securePrivateDirectory(outputDir, privateDirectoryOptions);\n await securedOutputDirectory.assertIdentityAt(outputDir);\n const outputDirectoryIdentity = await readDirectoryIdentity(outputDir);\n if (outputDirectoryIdentity === null) {\n throw new Error(\"OpenClaw Crabline smoke lock output directory is invalid.\");\n }\n const lockDirectory = path.join(outputDir, `.${OPENCLAW_CRABLINE_MANIFEST_PATH}.lock`);\n const token = randomUUID();\n const currentPid = dependencies.pid ?? process.pid;\n const getRuntimeProcessIdentity =\n dependencies.getProcessIdentity ??\n ((pid) => (pid === process.pid ? getCachedCurrentProcessIdentity() : getProcessIdentity(pid)));\n const getRuntimeProcessIdentityV2 =\n dependencies.getProcessIdentityV2 ??\n ((pid) =>\n pid === process.pid ? getCachedCurrentProcessIdentityV2() : getProcessIdentityV2(pid));\n const runtime: SmokeLockRuntime = {\n currentPid,\n currentProcessIdentity:\n dependencies.processIdentity === undefined\n ? getRuntimeProcessIdentity(currentPid)\n : dependencies.processIdentity,\n currentProcessIdentityV2:\n dependencies.processIdentityV2 === undefined\n ? getRuntimeProcessIdentityV2(currentPid)\n : dependencies.processIdentityV2,\n currentProcessStartedAtMs: dependencies.processStartedAtMs ?? CURRENT_PROCESS_STARTED_AT_MS,\n getProcessIdentity: getRuntimeProcessIdentity,\n getProcessIdentityV2: getRuntimeProcessIdentityV2,\n isProcessAlive: dependencies.isProcessAlive ?? isProcessAlive,\n leaseMs: dependencies.leaseMs ?? LOCK_LEASE_MS,\n now: dependencies.now ?? Date.now,\n sleep: dependencies.sleep ?? sleep,\n };\n const createdAtMs = runtime.now();\n if (\n !isValidProcessId(runtime.currentPid) ||\n (runtime.currentProcessIdentity !== null &&\n (runtime.currentProcessIdentity.length === 0 ||\n runtime.currentProcessIdentity.length > 256)) ||\n (runtime.currentProcessIdentityV2 !== null &&\n (runtime.currentProcessIdentityV2.length === 0 ||\n runtime.currentProcessIdentityV2.length > 256)) ||\n !isPositiveSafeInteger(runtime.currentProcessStartedAtMs) ||\n !isPositiveSafeInteger(runtime.leaseMs) ||\n !isPositiveSafeInteger(createdAtMs)\n ) {\n throw new Error(\"Invalid OpenClaw Crabline smoke lock runtime.\");\n }\n const owner: RenewableSmokeLockOwner = {\n channel: params.channel,\n createdAtMs,\n leaseVersion: 1,\n pid: runtime.currentPid,\n ...(runtime.currentProcessIdentity ? { processIdentity: runtime.currentProcessIdentity } : {}),\n ...(runtime.currentProcessIdentityV2\n ? { processIdentityV2: runtime.currentProcessIdentityV2 }\n : {}),\n processStartedAtMs: runtime.currentProcessStartedAtMs,\n token,\n };\n const compatibilityOwner: RenewableSmokeLockOwner = {\n ...owner,\n createdAtMs: 1,\n };\n\n for (;;) {\n const lockClaims = await listLockClaims(lockDirectory);\n if (lockClaims.length > 0 || (await pathExists(`${lockDirectory}${LEGACY_RECOVERY_SUFFIX}`))) {\n await resolveLockClaims({\n beforeRecoveryDeleteClaim:\n dependencies.beforeRecoveryDeleteClaim ?? (async () => undefined),\n lockDirectory,\n outputDir: requestedOutputDir,\n requestedChannel: params.channel,\n runtime,\n });\n continue;\n }\n\n const ownerDirectory = `${lockDirectory}${OWNED_CLAIM_SUFFIX}.${token}`;\n const { candidateDirectory, securedDirectory } = await createLockCandidate({\n ...(dependencies.afterLockOwnerWrite\n ? { afterOwnerWrite: dependencies.afterLockOwnerWrite }\n : {}),\n includeLease: false,\n lockDirectory,\n owner: compatibilityOwner,\n ...(dependencies.platform ? { platform: dependencies.platform } : {}),\n ...(dependencies.secureWindowsDirectory\n ? { secureWindowsDirectory: dependencies.secureWindowsDirectory }\n : {}),\n });\n let ownerCandidate: Awaited<ReturnType<typeof createLockCandidate>>;\n try {\n ownerCandidate = await createLockCandidate({\n candidateDirectory: `${lockDirectory}.${runtime.currentPid}.${token}.owned.tmp`,\n lockDirectory: ownerDirectory,\n owner,\n ...(dependencies.platform ? { platform: dependencies.platform } : {}),\n ...(dependencies.secureWindowsDirectory\n ? { secureWindowsDirectory: dependencies.secureWindowsDirectory }\n : {}),\n });\n } catch (error) {\n await fs.rm(candidateDirectory, { force: true, recursive: true }).catch(() => undefined);\n throw error;\n }\n let compatibilityMarkerHandle: FileHandle | undefined;\n try {\n compatibilityMarkerHandle = await fs.open(\n path.join(candidateDirectory, LOCK_OWNER_FILE),\n \"r+\",\n );\n const compatibilityRecord = await readLockRecordFromHandle(compatibilityMarkerHandle);\n if (compatibilityRecord.owner.token !== token) {\n throw new Error(\"OpenClaw Crabline smoke lock compatibility marker was replaced.\");\n }\n const activeAt = new Date(createdAtMs);\n await compatibilityMarkerHandle.utimes(activeAt, activeAt);\n await compatibilityMarkerHandle.sync();\n } catch (error) {\n await compatibilityMarkerHandle?.close().catch(() => undefined);\n await fs.rm(candidateDirectory, { force: true, recursive: true }).catch(() => undefined);\n await fs\n .rm(ownerCandidate.candidateDirectory, { force: true, recursive: true })\n .catch(() => undefined);\n throw error;\n }\n if (!compatibilityMarkerHandle) {\n throw new Error(\"OpenClaw Crabline smoke lock compatibility marker was not opened.\");\n }\n const markerHandle = compatibilityMarkerHandle;\n try {\n await fs.rename(candidateDirectory, lockDirectory);\n } catch (error) {\n await markerHandle.close().catch(() => undefined);\n await fs.rm(candidateDirectory, { force: true, recursive: true }).catch(() => undefined);\n await fs\n .rm(ownerCandidate.candidateDirectory, { force: true, recursive: true })\n .catch(() => undefined);\n await resolveLockContention({\n beforeRecoveryDeleteClaim:\n dependencies.beforeRecoveryDeleteClaim ?? (async () => undefined),\n cause: error,\n lockDirectory,\n outputDir: requestedOutputDir,\n requestedChannel: params.channel,\n runtime,\n beforeRecoveryClaim: dependencies.beforeRecoveryClaim ?? (async () => undefined),\n });\n continue;\n }\n let ownerInstalled = false;\n try {\n await dependencies.afterLockCandidateInstall?.(lockDirectory);\n await securedDirectory.assertIdentityAt(lockDirectory);\n const installed = await readLockRecord(lockDirectory);\n if (installed.kind !== \"record\" || installed.record.owner.token !== token) {\n await retireCompatibilityMarker(markerHandle, compatibilityOwner);\n await markerHandle.close();\n await fs.rm(ownerCandidate.candidateDirectory, { force: true, recursive: true });\n continue;\n }\n await fs.rename(ownerCandidate.candidateDirectory, ownerDirectory);\n ownerInstalled = true;\n await dependencies.afterLockOwnerClaimInstall?.(ownerDirectory);\n await ownerCandidate.securedDirectory.assertIdentityAt(ownerDirectory);\n } catch (error) {\n let cleanupError: unknown;\n try {\n if (ownerInstalled) {\n await removeOwnedLock({\n lockDirectory,\n ownedDirectory: ownerDirectory,\n token,\n });\n } else {\n await fs.rm(ownerCandidate.candidateDirectory, { force: true, recursive: true });\n }\n await retireCompatibilityMarker(markerHandle, compatibilityOwner);\n } catch (caughtCleanupError) {\n cleanupError = caughtCleanupError;\n }\n try {\n await markerHandle.close();\n } catch (closeError) {\n cleanupError =\n cleanupError === undefined\n ? closeError\n : new AggregateError(\n [cleanupError, closeError],\n \"OpenClaw Crabline smoke lock setup cleanup also failed.\",\n );\n }\n if (cleanupError !== undefined) {\n const aggregateError = new AggregateError(\n [error, cleanupError],\n \"OpenClaw Crabline smoke lock setup and cleanup failed.\",\n );\n aggregateError.cause = error;\n throw aggregateError;\n }\n throw error;\n }\n\n const competingClaims = (await listLockClaims(lockDirectory)).filter(\n (claim) => claim.directoryPath !== ownerDirectory,\n );\n if (\n competingClaims.length > 0 ||\n (await pathExists(`${lockDirectory}${LEGACY_RECOVERY_SUFFIX}`))\n ) {\n const removed = await removeOwnedLock({\n lockDirectory,\n ownedDirectory: ownerDirectory,\n token,\n });\n if (!removed) {\n await markerHandle.close();\n throw new Error(\"OpenClaw Crabline smoke lock ownership was lost.\");\n }\n try {\n await retireCompatibilityMarker(markerHandle, compatibilityOwner);\n } finally {\n await markerHandle.close();\n }\n await resolveLockClaims({\n beforeRecoveryDeleteClaim:\n dependencies.beforeRecoveryDeleteClaim ?? (async () => undefined),\n lockDirectory,\n outputDir: requestedOutputDir,\n requestedChannel: params.channel,\n runtime,\n });\n continue;\n }\n\n let ownedDirectory = ownerDirectory;\n let clockRegressed = false;\n let lastObservedNowMs = createdAtMs;\n let lastRenewedAtMs = createdAtMs;\n let pendingRenewal = Promise.resolve();\n let commitFenceConsumed = false;\n let markerClosed = false;\n let markerRetired = false;\n let heartbeat: HeartbeatController;\n const retireMarker = async () => {\n if (!markerRetired) {\n await retireCompatibilityMarker(markerHandle, compatibilityOwner);\n markerRetired = true;\n }\n if (!markerClosed) {\n await markerHandle.close();\n markerClosed = true;\n }\n };\n const renew = async () => {\n const renewal = pendingRenewal\n .catch(() => undefined)\n .then(async () => {\n const nowMs = runtime.now();\n if (nowMs < lastObservedNowMs) {\n clockRegressed = true;\n } else if (clockRegressed && nowMs >= lastRenewedAtMs) {\n clockRegressed = false;\n }\n lastObservedNowMs = nowMs;\n const renewedAtMs = clockRegressed ? lastRenewedAtMs + 1 : nowMs;\n if (!Number.isSafeInteger(renewedAtMs)) {\n throw new Error(\"OpenClaw Crabline smoke lock renewal timestamp overflowed.\");\n }\n if (!(await renewOwnedLock(ownedDirectory, token, renewedAtMs))) {\n throw new Error(\"OpenClaw Crabline smoke lock ownership was lost.\");\n }\n await dependencies.beforeCompatibilityMarkerRenew?.();\n if (\n !(await renewCompatibilityMarker({\n handle: markerHandle,\n lockDirectory,\n renewedAtMs,\n securedDirectory,\n token,\n }))\n ) {\n throw new Error(\"OpenClaw Crabline smoke lock compatibility marker was lost.\");\n }\n lastRenewedAtMs = renewedAtMs;\n });\n pendingRenewal = renewal;\n await renewal;\n };\n try {\n heartbeat = (dependencies.startHeartbeat ?? startHeartbeat)(\n renew,\n heartbeatIntervalMs(runtime.leaseMs),\n );\n } catch (error) {\n try {\n await removeOwnedLock({\n lockDirectory,\n ownedDirectory: ownerDirectory,\n token,\n });\n await retireMarker();\n } catch (cleanupError) {\n const aggregateError = new AggregateError(\n [error, cleanupError],\n \"OpenClaw Crabline smoke lock heartbeat startup and cleanup failed.\",\n );\n aggregateError.cause = error;\n throw aggregateError;\n }\n throw error;\n }\n let heartbeatStopped = false;\n let released = false;\n return {\n async assertOwned() {\n if (released || heartbeatStopped) {\n throw new Error(\"OpenClaw Crabline smoke lock has already been released.\");\n }\n heartbeat.assertHealthy();\n await renew();\n heartbeat.assertHealthy();\n await assertCompatibilityMarkerOwned({\n lockDirectory,\n securedDirectory,\n token,\n });\n },\n async commitFileAtomically({ contents, destinationPath, stageDirectory, stageFile }) {\n if (released) {\n throw new Error(\"OpenClaw Crabline smoke lock has already been released.\");\n }\n if (commitFenceConsumed || heartbeatStopped || ownedDirectory !== ownerDirectory) {\n throw new Error(\"OpenClaw Crabline smoke lock has already committed its fence.\");\n }\n heartbeat.assertHealthy();\n await renew();\n heartbeat.assertHealthy();\n\n const resolvedDestinationPath = await resolveConfinedPath(\n outputDir,\n destinationPath,\n \"commit destination\",\n \"file\",\n );\n const destinationDirectory = path.dirname(resolvedDestinationPath);\n const securedDestinationDirectory =\n destinationDirectory === outputDir\n ? securedOutputDirectory\n : await securePrivateDirectory(destinationDirectory, privateDirectoryOptions);\n await securedDestinationDirectory.assertIdentityAt(destinationDirectory);\n const destinationDirectoryIdentity = await readDirectoryIdentity(destinationDirectory);\n if (destinationDirectoryIdentity === null) {\n throw new Error(\"OpenClaw Crabline smoke lock commit destination is invalid.\");\n }\n if (destinationDirectoryIdentity.device !== outputDirectoryIdentity.device) {\n throw new Error(\n \"OpenClaw Crabline smoke lock commit destination is on another filesystem.\",\n );\n }\n const resolvedStageDirectory = stageDirectory\n ? await resolveConfinedPath(\n outputDir,\n stageDirectory,\n \"commit stage directory\",\n \"directory\",\n )\n : ownerDirectory;\n let stageDirectoryIdentity: DirectoryIdentity | null = null;\n if (stageDirectory) {\n try {\n stageDirectoryIdentity = await readDirectoryIdentity(resolvedStageDirectory);\n } catch (error) {\n throw new Error(\"OpenClaw Crabline smoke lock commit stage directory is invalid.\", {\n cause: error,\n });\n }\n }\n if (stageDirectory && stageDirectoryIdentity === null) {\n throw new Error(\"OpenClaw Crabline smoke lock commit stage directory is invalid.\");\n }\n if (\n stageDirectoryIdentity !== null &&\n stageDirectoryIdentity.device !== outputDirectoryIdentity.device\n ) {\n throw new Error(\n \"OpenClaw Crabline smoke lock commit stage directory is on another filesystem.\",\n );\n }\n const stagedFileName = `.commit-file.${token}.${randomUUID()}.tmp`;\n const stagedFilePath = path.join(ownerDirectory, stagedFileName);\n await stageFile(stagedFilePath, contents);\n if (stageDirectory) {\n if (\n !hasSameDirectoryIdentity(\n stageDirectoryIdentity,\n await readDirectoryIdentity(resolvedStageDirectory),\n )\n ) {\n throw new Error(\n \"OpenClaw Crabline smoke lock commit stage directory identity changed.\",\n );\n }\n }\n const stagedFileIdentity = await readFileIdentity(stagedFilePath);\n if (stagedFileIdentity === null) {\n throw new Error(\"OpenClaw Crabline smoke lock commit stage file is invalid.\");\n }\n heartbeat.assertHealthy();\n await renew();\n heartbeat.assertHealthy();\n\n await dependencies.beforeCommitClaim?.();\n await assertCompatibilityMarkerOwned({\n lockDirectory,\n securedDirectory,\n token,\n });\n const commitClaim = `${lockDirectory}${COMMIT_CLAIM_SUFFIX}.${token}.${randomUUID()}`;\n const observedIdentity = await readDirectoryIdentity(ownerDirectory);\n const observed = await readLockRecord(ownerDirectory);\n if (\n observedIdentity === null ||\n observed.kind === \"missing\" ||\n observed.record.owner.token !== token\n ) {\n throw new Error(\"OpenClaw Crabline smoke lock ownership was lost.\");\n }\n\n try {\n await fs.rename(ownerDirectory, commitClaim);\n } catch (error) {\n if (isMissingPathError(error)) {\n throw new Error(\"OpenClaw Crabline smoke lock ownership was lost.\", {\n cause: error,\n });\n }\n throw error;\n }\n ownedDirectory = commitClaim;\n commitFenceConsumed = true;\n\n const claimed = await readLockRecord(commitClaim);\n const claimedIdentity = await readDirectoryIdentity(commitClaim);\n if (\n claimed.kind === \"missing\" ||\n claimed.record.owner.token !== token ||\n !hasSameDirectoryIdentity(observedIdentity, claimedIdentity)\n ) {\n if (!(await pathExists(ownerDirectory))) {\n try {\n await fs.rename(commitClaim, ownerDirectory);\n ownedDirectory = ownerDirectory;\n } catch (error) {\n if (!isMissingPathError(error)) {\n throw error;\n }\n }\n }\n throw new Error(\"OpenClaw Crabline smoke lock commit fence was lost.\");\n }\n\n await dependencies.beforeCommitFileRename?.();\n heartbeat.assertHealthy();\n await renew();\n heartbeat.assertHealthy();\n await heartbeat.settle();\n heartbeat.assertHealthy();\n await dependencies.beforeCommitRename?.();\n await assertCompatibilityMarkerOwned({\n lockDirectory,\n securedDirectory,\n token,\n });\n const claimedStagedFilePath = path.join(commitClaim, stagedFileName);\n if (stageDirectory) {\n const currentDirectoryIdentity = await readDirectoryIdentity(resolvedStageDirectory);\n const currentFileIdentity = await readFileIdentity(claimedStagedFilePath);\n if (\n !hasSameDirectoryIdentity(stageDirectoryIdentity, currentDirectoryIdentity) ||\n !hasSameDirectoryIdentity(stagedFileIdentity, currentFileIdentity)\n ) {\n const error = new Error(\"OpenClaw Crabline smoke lock commit stage identity changed.\");\n Object.assign(error, { code: \"ENOENT\", path: claimedStagedFilePath });\n throw error;\n }\n } else if (\n !hasSameDirectoryIdentity(\n stagedFileIdentity,\n await readFileIdentity(claimedStagedFilePath),\n )\n ) {\n throw new Error(\"OpenClaw Crabline smoke lock commit stage identity changed.\");\n }\n if (\n !hasSameDirectoryIdentity(outputDirectoryIdentity, await readDirectoryIdentity(outputDir))\n ) {\n throw new Error(\"OpenClaw Crabline smoke lock output directory identity changed.\");\n }\n await securedOutputDirectory.assertIdentityAt(outputDir);\n let currentDestinationDirectoryIdentity: DirectoryIdentity | null = null;\n try {\n currentDestinationDirectoryIdentity = await readDirectoryIdentity(destinationDirectory);\n } catch {\n // A replaced directory or symlink is an identity mismatch.\n }\n if (\n !hasSameDirectoryIdentity(\n destinationDirectoryIdentity,\n currentDestinationDirectoryIdentity,\n )\n ) {\n throw new Error(\n \"OpenClaw Crabline smoke lock commit destination directory identity changed.\",\n );\n }\n await securedDestinationDirectory.assertIdentityAt(destinationDirectory);\n const revalidatedDestinationPath = await resolveConfinedPath(\n outputDir,\n resolvedDestinationPath,\n \"commit destination\",\n \"file\",\n );\n if (revalidatedDestinationPath !== resolvedDestinationPath) {\n throw new Error(\"OpenClaw Crabline smoke lock commit destination path identity changed.\");\n }\n // The owner-only output tree and smoke lock serialize supported writers; confinement does\n // not treat another process running as the same OS user as a lower-privilege adversary.\n await fs.rename(claimedStagedFilePath, revalidatedDestinationPath);\n },\n async release() {\n if (released) {\n return;\n }\n if (!heartbeatStopped) {\n heartbeatStopped = true;\n try {\n await heartbeat.stop();\n } finally {\n await pendingRenewal.catch(() => undefined);\n }\n } else {\n await pendingRenewal.catch(() => undefined);\n }\n await removeOwnedLock({\n ...(dependencies.beforeReleaseClaim\n ? { beforeClaim: dependencies.beforeReleaseClaim }\n : {}),\n ...(dependencies.beforeReleaseRename\n ? { beforeRename: dependencies.beforeReleaseRename }\n : {}),\n ...(dependencies.beforeReleaseRemove\n ? { beforeRemove: dependencies.beforeReleaseRemove }\n : {}),\n lockDirectory,\n onOwnedDirectoryChange: (directoryPath) => {\n ownedDirectory = directoryPath;\n },\n ownedDirectory,\n ...(dependencies.removeDirectory\n ? { removeDirectory: dependencies.removeDirectory }\n : {}),\n token,\n });\n await claimLegacyRecoveryDirectory(lockDirectory, token);\n for (const claim of await listLockClaims(lockDirectory)) {\n await removeOwnedLock({\n lockDirectory,\n ownedDirectory: claim.directoryPath,\n ...(dependencies.removeDirectory\n ? { removeDirectory: dependencies.removeDirectory }\n : {}),\n token,\n });\n }\n await retireMarker();\n released = true;\n },\n };\n }\n}\n\nexport async function releaseOpenClawCrablineSmokeRunLock(\n lock: Pick<OpenClawCrablineSmokeRunLock, \"release\">,\n dependencies: {\n sleep?: Sleep;\n } = {},\n): Promise<void> {\n for (let attempt = 1; ; attempt += 1) {\n try {\n await lock.release();\n return;\n } catch (error) {\n if (attempt === RELEASE_ATTEMPTS) {\n throw error;\n }\n await (dependencies.sleep ?? sleep)(RELEASE_RETRY_DELAY_MS * 2 ** (attempt - 1));\n }\n }\n}\n"]}
|