updateSpec method
Swaps the enforced spec live; the next exec uses the new policies.
A backend: kernel spec with no enforcing backend for the host
refuses (every command denied, nothing runs) unless the spec opts in
via allowDegrade, in which case it degrades to policy mode and
fires onDegrade.
Implementation
void updateSpec(CubeSpec spec) {
_spec = spec;
_refusal = null;
_engine = CubePolicyEngine(
spec,
homeDir: _homeDir,
workspaceRoot: _fs?.cwd,
pathProbe: _pathProbe,
);
_kernel = _kernelRunFor(spec);
if (_kernel == null && spec.backend == CubeBackendMode.kernel) {
if (spec.allowDegrade) {
onDegrade?.call(
'fa_cube[${spec.name}]: kernel backend unavailable, '
'running in policy mode',
);
} else {
_refusal =
'fa_cube[${spec.name}]: backend: kernel is not available on '
'this platform and the run refuses to fall back to policy '
'mode — set spec.allowDegrade: true to allow the degrade';
}
return;
}
final blocked = _kernel?.blockedNote;
if (blocked != null) {
if (spec.allowDegrade) {
// The explicit escape hatch: the staging location cannot be
// trusted, so kernel mode is undeliverable — degrade instead of
// hard-locking the spec (same contract as the unavailable
// backend above).
_kernel = null;
onDegrade?.call(
'fa_cube[${spec.name}]: kernel backend $blocked, '
'allowDegrade set — running in policy mode',
);
}
// Without the opt-in the per-exec path fail-closes with the
// remediation in the note (see [_KernelRun.stageVerified]).
}
}