feat(lease): verified lease-remediation stack (rebased onto next) — promotion trigger + promote CLI + carve-out + TTL #1109

Open
mos-dt-0 wants to merge 24 commits from feat/lease-promotion-and-harness-isolation into next
Showing only changes of commit de0adb9207 - Show all commits
@@ -64,7 +64,7 @@ describe('TmuxPromotionTransport', () => {
// transport must WALK the subtree. This test exercises the real walk (no
// full mock of the resolution) — the seam the original unit test hid.
it('walks the pane subtree to the claude child that carries the lease id', async () => {
const runner = vi.fn<CommandRunner>().mockResolvedValueOnce(result('1234 claude 0 0 0 0\n'));
const runner = vi.fn<CommandRunner>().mockResolvedValueOnce(result('1234 node 0 0 0 0\n'));
// pane pid 1234 = node(mosaic): NO lease env. child 5678 = claude: carries it.
const environmentReader = vi.fn(async (pid: number) =>
pid === 5678 ? `FOO=bar\0MOSAIC_LEASE_SESSION_ID=${sessionId}\0` : `FOO=bar\0`,
@@ -87,7 +87,7 @@ describe('TmuxPromotionTransport', () => {
});
it('fails closed when no process in the pane subtree carries a lease id', async () => {
const runner = vi.fn<CommandRunner>().mockResolvedValueOnce(result('1234 claude 0 0 0 0\n'));
const runner = vi.fn<CommandRunner>().mockResolvedValueOnce(result('1234 node 0 0 0 0\n'));
const environmentReader = vi.fn(async () => `FOO=bar\0`);
const childrenReader = vi.fn(async (pid: number) => (pid === 1234 ? [5678] : []));
const transport = new TmuxPromotionTransport({