Spike: a policy mod whose tool.call hook blocks the hooks worker

<h1>nixie</h1>
A personal assistant platform that its owner runs and controls: every rule readable and editable, every decision recorded, and personal data kept on the owner's own hosts.
<a href="./docs/README.md">Documentation</a> • <a href="./docs/README.md#decisions">Decisions</a> • <a href="./AGENTS.md">Agent Guidelines</a>
nixie is in Phase 2, Research, and has no product code. The work runs in 4 phases: brainstorm, research, design, and decide. Decisions are recorded as research settles each question.
bun install
bun run check # format, lint, and the prose check
hooks/register.js 37 lines1// The MARK_BLOCK hook never yields, so the hooks worker stops answering.
2// /nixie-alive answers only while the module is loaded, so a host can probe for it.
3async function handleSessionStart($, e, next) {
4 await $.command.register({
5 description: 'Report that the nixie policy mod is loaded',
6 immediate: true,
7 name: 'nixie-alive',
8 });
9 return next(e);
10}
11
12function handleAliveCommand() {
13 return { text: 'nixie-policy alive' };
14}
15
16function runForever() {
17 while (true) {
18 // Spin without awaiting.
19 }
20}
21
22function checkBash($, e, next) {
23 if (e.command.includes('MARK_BLOCK')) {
24 runForever();
25 }
26 if (e.command.includes('MARK_DENY')) {
27 return { deny: 'nixie-busy-loop denied this command.' };
28 }
29 return next(e);
30}
31
32export function register(on) {
33 on('session.start', handleSessionStart);
34 on('command.run', { command: 'nixie-alive' }, handleAliveCommand);
35 on('tool.call', { tool: 'Bash' }, checkBash);
36}
37