Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 4 additions & 3 deletions docs/reference/canonical-lease-renew.md
Original file line number Diff line number Diff line change
Expand Up @@ -95,9 +95,10 @@ if retained repository metadata differs for that physical checkout.
Requests without a verified caller workspace retain ordinary exclusive scope
checks, including against unknown legacy grants. Repository mismatch,
redirected paths and a non-worktree root fail closed. Verified machine discovery
currently supports macOS and Linux; other hosts retain ordinary leases. No
workspace path or machine identifier is stored directly: only opaque digests
and the existing public repository identity enter the private authority record.
currently supports macOS, Linux and Windows; other hosts retain ordinary
leases. No workspace path or machine identifier is stored directly: only
opaque digests and the existing public repository identity enter the private
authority record.

Renewal preserves this identity. Acquire retries must use the same worktree,
scopes and execution key; an alias resolving to the same worktree is valid.
Expand Down
19 changes: 16 additions & 3 deletions loopx/control_plane/work_items/task_lease_workspace.ts
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,21 @@ export function sameLeaseCheckout(left: unknown, right: unknown): boolean {
a.worktree === b.worktree;
}

/** The platform's OS-installation identity for worktree isolation; unsupported hosts stay fail-closed. */
async function machineIdentity(): Promise<string | undefined> {
if (platform() === "darwin") {
return /"IOPlatformUUID"\s*=\s*"([^"]+)"/u.exec((await run("ioreg", ["-rd1", "-c", "IOPlatformExpertDevice"], {timeout: 5000})).stdout)?.[1];
}
if (platform() === "linux") return (await readFile("/etc/machine-id", "utf8")).trim();
if (platform() === "win32") {
// MachineGuid is the Windows analog of /etc/machine-id: this OS
// installation's identity, not a user-changeable computer name.
return /MachineGuid\s+REG_SZ\s+([0-9a-fA-F-]{36})/u.exec((await run("reg",
["query", "HKLM\\SOFTWARE\\Microsoft\\Cryptography", "/v", "MachineGuid"], {timeout: 5000})).stdout)?.[1];
}
return undefined;
}

export async function observeLeaseWorktree(path: string, overlaps: (path: string) => boolean): Promise<LeaseWorkspace> {
if (!isAbsolute(path)) throw new LeaseWorktreeObservationError("worktree observation requires an absolute caller path");
const cwd = await realpath(path);
Expand Down Expand Up @@ -132,9 +147,7 @@ export async function observeLeaseWorktree(path: string, overlaps: (path: string
// Private local paths are not persisted. Filesystem inode identity collapses
// symlink/case aliases; a recreated directory gets a new identity.
const key = async (p: string) => {const s = await stat(p); return digest(`${s.dev}:${s.ino}`);};
const machine = platform() === "darwin"
? /"IOPlatformUUID"\s*=\s*"([^"]+)"/u.exec((await run("ioreg", ["-rd1", "-c", "IOPlatformExpertDevice"], {timeout: 5000})).stdout)?.[1]
: platform() === "linux" ? (await readFile("/etc/machine-id", "utf8")).trim() : null;
const machine = await machineIdentity();
if (!machine) throw new LeaseWorktreeObservationError("host identity unavailable for worktree isolation");
return {host: digest(machine), common_directory: await key(common), worktree: await key(root), repository};
}
2 changes: 1 addition & 1 deletion tests/control_plane/test_task_lease_cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
ROOT = Path(__file__).resolve().parents[2]


@pytest.mark.skipif(sys.platform not in {"darwin", "linux"}, reason="Native worktree host identity requires macOS or Linux")
@pytest.mark.skipif(sys.platform not in {"darwin", "linux"}, reason="worktree lease fixture requires symlinks; Windows needs Developer Mode")
@pytest.mark.parametrize("provider", ["file", "sqlite"])
def test_dependency_links_replay_and_recovery_preserve_real_lease_authority(tmp_path, monkeypatch, provider):
isolate_sqlite_runtime(tmp_path, monkeypatch)
Expand Down
4 changes: 3 additions & 1 deletion tests/control_plane_ts/task_lease_workspace.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ test("native observation never interprets a caller path relative to the worker",
});

test("observed Git origins use the Todo repository identity contract", {
skip: !["darwin", "linux"].includes(platform()),
skip: !["darwin", "linux", "win32"].includes(platform()),
}, async t => {
const temporary = await mkdtemp(join(tmpdir(), "loopx-lease-origin-"));
t.after(() => rm(temporary, {recursive: true, force: true}));
Expand Down Expand Up @@ -58,6 +58,8 @@ test("observed Git origins use the Todo repository identity contract", {
}
});

// Creating file symlinks needs Developer Mode or administrator rights on
// Windows; the machine-identity path is covered by the observation test above.
test("normal executable file links preserve the declared independent checkout", {
skip: !["darwin", "linux"].includes(platform()),
}, async t => {
Expand Down
2 changes: 1 addition & 1 deletion tests/test_task_lease_worktree.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
from loopx.control_plane.coordination.runtime_shadow import build_todo_runtime_shadow_projection


@pytest.mark.skipif(sys.platform not in {"darwin", "linux"}, reason="verified host identity currently supports macOS/Linux")
@pytest.mark.skipif(sys.platform not in {"darwin", "linux"}, reason="worktree lease fixture requires symlinks; Windows needs Developer Mode")
@pytest.mark.parametrize("provider", ["file", "sqlite"])
@pytest.mark.parametrize("origin,repository", [
("https://github.com/example/project.git", "git:github.com/example/project"),
Expand Down
Loading