WI-3 (#830): compaction observers → revoke + D4 same-PID generation auto-revoke (#842)
All checks were successful
ci/woodpecker/push/publish Pipeline was successful
ci/woodpecker/push/ci Pipeline was successful

This commit was merged in pull request #842.
This commit is contained in:
2026-07-19 19:46:28 +00:00
parent 8dfcf1903e
commit e4d7d4502d
21 changed files with 1278 additions and 42 deletions

View File

@@ -22,6 +22,7 @@ import {
import { join, basename } from 'node:path';
import { homedir } from 'node:os';
import { execSync, spawnSync } from 'node:child_process';
import { registerLeaseLifecycleHooks, type LeaseLifecyclePiApi } from './lease-lifecycle.js';
// ---------------------------------------------------------------------------
// Config
@@ -29,6 +30,7 @@ import { execSync, spawnSync } from 'node:child_process';
const MOSAIC_HOME = process.env['MOSAIC_HOME'] ?? join(homedir(), '.config', 'mosaic');
const MUTATOR_GATE = join(MOSAIC_HOME, 'tools', 'lease-broker', 'mutator-gate.py');
const LEASE_REVOKER = join(MOSAIC_HOME, 'tools', 'lease-broker', 'revoke-lease.py');
// ---------------------------------------------------------------------------
// Helpers
@@ -107,6 +109,15 @@ function nowIso(): string {
return new Date().toISOString().replace(/\.\d{3}Z$/, 'Z');
}
function runPiLeaseRevoker(args: string[]): boolean {
const result = spawnSync('python3', [LEASE_REVOKER, ...args], {
encoding: 'utf8',
timeout: 2_000,
env: process.env,
});
return result.status === 0;
}
function checkPiMutatorGate(toolName: string): { block: true; reason: string } | undefined {
const result = spawnSync('python3', [MUTATOR_GATE, '--runtime', 'pi'], {
input: `${JSON.stringify({ tool_name: toolName })}\n`,
@@ -268,6 +279,9 @@ export default function register(pi: ExtensionAPI) {
let hbModel: string | null = null;
let hbTimer: ReturnType<typeof setInterval> | null = null;
// ── Compaction observers and same-PID generation rollover ─────────────
registerLeaseLifecycleHooks(pi as unknown as LeaseLifecyclePiApi, runPiLeaseRevoker);
// ── Whole mutator-class authorization gate ────────────────────────────
// Every Pi tool, including unknown/custom tools, reaches the broker-backed
// class gate before execution. Broker/script failure blocks fail-closed.