feat(protocol): deliver Activity Lease model (Zero Background Workers)

Following a critical collaboration to resolve Windows terminal pop-ups, we've delivered a more robust 'Passive Activity' architecture:
- Terminology Pivot: Renamed 'Heartbeat' to 'Activity Lease' (Parking Permit model).
- Side-Effect Extension: tools/bb.ts now automatically extends the agent's lease whenever they perform real work (any CLI command).
- Passive Handshake: bb-init.mjs now only performs an initial registration/lease start, with no background loops.
- 100% Silence: Removed all background process spawning, ensuring zero terminal disruption on Windows.
- High Observability: Liveness is still tracked via the 15m threshold, but relies on activity rather than periodic pings.

OPERATIVE: silver-castle
SESSION: 2026-02-14-1330
This commit is contained in:
zenchantlive 2026-02-14 11:18:40 -08:00
parent 5b9c0aa6a3
commit e010e0b10b
6 changed files with 69 additions and 59 deletions

View file

@ -10,7 +10,7 @@ const initScript = path.join(projectRoot, 'scripts', 'bb-init.mjs');
async function withTempRegistry(run: (tempDir: string) => Promise<void>): Promise<void> {
const previous = process.env.USERPROFILE;
const tempDir = await fs.mkdtemp(path.join(os.tmpdir(), 'bb-init-passive-'));
const tempDir = await fs.mkdtemp(path.join(os.tmpdir(), 'bb-init-lease-'));
process.env.USERPROFILE = tempDir;
// Initialize a fake git repo
@ -22,13 +22,21 @@ async function withTempRegistry(run: (tempDir: string) => Promise<void>): Promis
await run(tempDir);
} finally {
process.env.USERPROFILE = previous;
await fs.rm(tempDir, { recursive: true, force: true, maxRetries: 5 });
// Cleanup with retries for Windows
for (let i = 0; i < 5; i++) {
try {
await fs.rm(tempDir, { recursive: true, force: true });
break;
} catch {
await new Promise(r => setTimeout(r, 500));
}
}
}
}
test('PASSIVE: bb-init --register updates liveness via side-effect', async (t) => {
test('LEASE: bb-init --register updates liveness and starts lease', async () => {
await withTempRegistry(async (tempDir) => {
const agentId = 'passive-agent';
const agentId = 'lease-agent';
const cmd = `node ${initScript} --register ${agentId} --role backend --json`;
const out = execSync(cmd, {
@ -39,7 +47,7 @@ test('PASSIVE: bb-init --register updates liveness via side-effect', async (t) =
const result = JSON.parse(out);
assert.equal(result.ok, true);
assert.equal(result.heartbeat.status, 'passive');
assert.equal(result.lease.status, 'active');
// Verify Registry Entry exists and has a timestamp
const agentFile = path.join(tempDir, '.beadboard', 'agent', 'agents', `${agentId}.json`);
@ -49,35 +57,27 @@ test('PASSIVE: bb-init --register updates liveness via side-effect', async (t) =
});
});
test('PASSIVE: bb-init --adopt rejection still works with noise filtering', async (t) => {
test('LEASE: activity-lease command works via CLI', async () => {
await withTempRegistry(async (tempDir) => {
const agentId = 'noise-agent';
// Register first
const agentId = 'cli-agent';
// Register
execSync(`node ${initScript} --register ${agentId} --role test --json`, {
cwd: tempDir,
env: { ...process.env, BB_REPO: projectRoot }
});
// Rejects with only .beadboard noise
try {
execSync(`node ${initScript} --adopt ${agentId} --non-interactive --json`, {
cwd: tempDir,
stdio: 'pipe',
env: { ...process.env, BB_REPO: projectRoot }
});
assert.fail('Should have rejected adoption');
} catch (err: any) {
const res = JSON.parse(err.stdout.toString());
assert.equal(res.error.code, 'ADOPTION_REJECTED');
}
const agentFile = path.join(tempDir, '.beadboard', 'agent', 'agents', `${agentId}.json`);
const firstSeen = JSON.parse(await fs.readFile(agentFile, 'utf8')).last_seen_at;
// Accepts with real change
await fs.writeFile(path.join(tempDir, 'real.ts'), 'code');
const adoptOut = execSync(`node ${initScript} --adopt ${agentId} --non-interactive --json`, {
cwd: tempDir,
// Extend lease
await new Promise(r => setTimeout(r, 100)); // Ensure clock tick
const bbPath = path.join(projectRoot, 'tools', 'bb.ts');
execSync(`npx tsx ${bbPath} agent activity-lease --agent ${agentId} --json`, {
cwd: tempDir,
env: { ...process.env, BB_REPO: projectRoot }
});
assert.equal(JSON.parse(adoptOut).ok, true);
const secondSeen = JSON.parse(await fs.readFile(agentFile, 'utf8')).last_seen_at;
assert.notEqual(firstSeen, secondSeen, 'Lease extension should update last_seen_at');
});
});
});