Delete Windows Void rumination authority

This commit is contained in:
Meta Vens 2026-07-16 05:58:31 +01:00
commit 5b35fd9fd2
25 changed files with 42 additions and 3561 deletions

View file

@ -1,92 +0,0 @@
param(
[string] $TaskName,
[int] $IntervalMinutes,
[switch] $RunNow
)
Set-StrictMode -Version Latest
$ErrorActionPreference = "Stop"
$ProgressPreference = "SilentlyContinue"
$repoRoot = Split-Path -Parent $PSScriptRoot
$envFile = Join-Path $repoRoot ".env"
$runnerScript = Join-Path $PSScriptRoot "run-void-moderator-rumination.ps1"
$hiddenLauncher = Join-Path $PSScriptRoot "run-hidden-powershell.vbs"
function Read-DotEnv {
param(
[Parameter(Mandatory = $true)]
[string] $Path
)
$values = @{}
if (-not (Test-Path $Path)) {
return $values
}
foreach ($line in Get-Content -Path $Path) {
if ([string]::IsNullOrWhiteSpace($line)) {
continue
}
if ($line.TrimStart().StartsWith("#")) {
continue
}
$separatorIndex = $line.IndexOf("=")
if ($separatorIndex -lt 1) {
continue
}
$key = $line.Substring(0, $separatorIndex).Trim()
$value = $line.Substring($separatorIndex + 1)
$values[$key] = $value
}
return $values
}
$config = Read-DotEnv -Path $envFile
$taskNameValue = if (-not [string]::IsNullOrWhiteSpace($TaskName)) {
$TaskName
} elseif ($config.ContainsKey("VOIDBOT_MODERATION_TASK_NAME") -and -not [string]::IsNullOrWhiteSpace($config["VOIDBOT_MODERATION_TASK_NAME"])) {
$config["VOIDBOT_MODERATION_TASK_NAME"]
} else {
"Void Moderator Rumination"
}
$intervalMinutesValue = if ($PSBoundParameters.ContainsKey("IntervalMinutes")) {
$IntervalMinutes
} elseif ($config.ContainsKey("VOIDBOT_MODERATION_INTERVAL_MINUTES") -and -not [string]::IsNullOrWhiteSpace($config["VOIDBOT_MODERATION_INTERVAL_MINUTES"])) {
[int]$config["VOIDBOT_MODERATION_INTERVAL_MINUTES"]
} else {
15
}
if ($intervalMinutesValue -lt 15) {
throw "VOIDBOT_MODERATION_INTERVAL_MINUTES must be at least 15."
}
$startAt = (Get-Date).AddMinutes(2)
$action = New-ScheduledTaskAction -Execute "wscript.exe" -Argument "//B //nologo `"$hiddenLauncher`" -NoProfile -NonInteractive -WindowStyle Hidden -ExecutionPolicy Bypass -File `"$runnerScript`"" -WorkingDirectory $repoRoot
$trigger = New-ScheduledTaskTrigger -Once -At $startAt -RepetitionInterval (New-TimeSpan -Minutes $intervalMinutesValue) -RepetitionDuration (New-TimeSpan -Days 3650)
$settings = New-ScheduledTaskSettingsSet -StartWhenAvailable -AllowStartIfOnBatteries -DontStopIfGoingOnBatteries -ExecutionTimeLimit (New-TimeSpan -Minutes 14) -MultipleInstances IgnoreNew
$principal = New-ScheduledTaskPrincipal -UserId "$env:USERDOMAIN\$env:USERNAME" -LogonType Interactive -RunLevel Limited
$description = "Runs Void's scheduled moderation-participation loop from the VoidBot workspace every $intervalMinutesValue minutes with real Codex tooling and local bot-voice output."
Register-ScheduledTask -TaskName $taskNameValue -Action $action -Trigger $trigger -Settings $settings -Principal $principal -Description $description -Force | Out-Null
Write-Host "Installed scheduled task: $taskNameValue"
Write-Host "Schedule: every $intervalMinutesValue minute(s), starting at $($startAt.ToString('yyyy-MM-dd HH:mm'))"
Write-Host "Task runs as: $($env:USERDOMAIN)\$($env:USERNAME)"
Write-Host "Logon mode: Interactive"
Write-Host "Launcher: wscript.exe hidden PowerShell shim"
Write-Host "Working directory: $repoRoot"
Write-Host "Execution time limit: 14 minutes"
Write-Host "Runner script: $runnerScript"
if ($RunNow) {
Start-ScheduledTask -TaskName $taskNameValue
Write-Host "Started task immediately."
}

View file

@ -478,8 +478,6 @@ try {
$agentSwarmPaused = Test-AgentSwarmPaused
$agentSwarmOrganIds = @{
"bifrost-dispatch" = $true
"void-moderation-heartbeat" = $true
"void-moderation-rumination" = $true
}
$onlySet = @{}
$onlyValues = @()
@ -509,24 +507,6 @@ try {
Executable = $node
Arguments = @((Join-Path $PSScriptRoot "render-voidbot-swarm-dashboard.mjs"))
},
[pscustomobject]@{
Id = "void-moderation-heartbeat"
Label = "Void rules moderation heartbeat"
IntervalMinutes = Get-ConfigInt -Config $config -Name "VOIDBOT_MODERATION_HEARTBEAT_INTERVAL_MINUTES" -Default 1 -Minimum 1
TimeoutMinutes = Get-ConfigInt -Config $config -Name "VOIDBOT_MODERATION_HEARTBEAT_TIMEOUT_MINUTES" -Default 3 -Minimum 1
Cwd = $repoRoot
Executable = $powershell
Arguments = @("-NoProfile", "-NonInteractive", "-ExecutionPolicy", "Bypass", "-File", (Join-Path $PSScriptRoot "run-void-moderator-rumination.ps1"), "-ModerationHeartbeatOnly")
},
[pscustomobject]@{
Id = "void-moderation-rumination"
Label = "Void moderation rumination"
IntervalMinutes = Get-ConfigInt -Config $config -Name "VOIDBOT_MODERATION_INTERVAL_MINUTES" -Default 15 -Minimum 15
TimeoutMinutes = 20
Cwd = $repoRoot
Executable = $powershell
Arguments = @("-NoProfile", "-NonInteractive", "-ExecutionPolicy", "Bypass", "-File", (Join-Path $PSScriptRoot "run-void-moderator-rumination.ps1"))
},
[pscustomobject]@{
Id = "voidbot-operations-watchdog"
Label = "VoidBot operations watchdog"
@ -548,16 +528,6 @@ try {
Write-JsonFile -Path $statePath -Data $state
continue
}
if ($organ.Id -eq "void-moderation-heartbeat" -and -not (Get-ConfigBool -Config $config -Name "VOIDBOT_MODERATION_HEARTBEAT_ENABLED" -Default $true)) {
Set-SkippedOrganState -State $state -Organ $organ -Now $now -Status "skipped_disabled"
Write-JsonFile -Path $statePath -Data $state
continue
}
if ($organ.Id -eq "void-moderation-rumination" -and -not (Get-ConfigBool -Config $config -Name "VOIDBOT_MODERATION_RUMINATION_ENABLED" -Default $true)) {
Set-SkippedOrganState -State $state -Organ $organ -Now $now -Status "skipped_disabled"
Write-JsonFile -Path $statePath -Data $state
continue
}
if ($organ.Id -eq "voidbot-operations-watchdog" -and -not (Get-ConfigBool -Config $config -Name "VOIDBOT_OPERATIONS_WATCHDOG_ENABLED" -Default $true)) {
Set-SkippedOrganState -State $state -Organ $organ -Now $now -Status "skipped_disabled"
Write-JsonFile -Path $statePath -Data $state

File diff suppressed because it is too large Load diff

View file

@ -76,7 +76,6 @@ import { projectPersonaCuriosityContext } from "../apps/persona-scheduler/dist/p
import { projectPersonaConversation, renderPersonaRoomTopicSaturation } from "../apps/persona-scheduler/dist/persona-conversation-projector.js";
import { buildPersonaJurisdictionDiveDirective, buildPersonaTurnPrompt } from "../apps/persona-scheduler/dist/persona-turn-prompt-projector.js";
import { assemblePersonaTurn } from "../apps/persona-scheduler/dist/persona-turn-assembler.js";
import { buildVoidModerationLaunchCommand, launchVoidModerationTurn, waitForVoidModerationHandshake } from "../apps/persona-scheduler/dist/void-moderation-turn-actuator.js";
import { readGlobalAgentDoctrine } from "../apps/persona-scheduler/dist/global-agent-doctrine-source.js";
import { buildInspectionParticipant } from "../apps/persona-scheduler/dist/inspection-participant-factory.js";
import { runPersonaSchedulerTick } from "../apps/persona-scheduler/dist/persona-scheduler-runner.js";
@ -848,9 +847,8 @@ const moderationHeldPhysiology = projectVoidPhysiology({ state: physiologyState,
assert.deepEqual(moderationHeldPhysiology.operations.map((operation) => operation.operation), ["update_speaking_pressure"], "active moderation freezes sleep ownership but does not prevent typed speech-pressure refresh");
assert.equal(moderationHeldPhysiology.memoryMaintenanceIntent, undefined, "moderation-held physiology cannot launch maintenance behind the moderation organ");
const appliedPhysiologyOperations: string[] = [];
const physiologyOrgan = await runVoidPhysiologyOrgan({ statePath: "void-self-state.cc", statusDirectory: "status", observedAt: physiologyObservedAt }, {
const physiologyOrgan = await runVoidPhysiologyOrgan({ statePath: "void-self-state.cc", observedAt: physiologyObservedAt }, {
loadState: async () => physiologyState,
readModerationActivity: async ({ lockPath }) => ({ active: false, lockPath }),
applyOperation: async (_store, operation) => { appliedPhysiologyOperations.push(operation.operation); return physiologyState; },
});
assert.deepEqual(appliedPhysiologyOperations, ["update_sleep_cycle", "update_speaking_pressure"], "the daemon physiology organ applies only domain-projected typed operations through the state-service port");
@ -1102,45 +1100,6 @@ const moderationModelOutput = await projectVoidModerationOperations({ prompt: "R
assert.match(moderationModelOutput, /reviewedMessageIds/, "the portable moderation actuator returns only model text to the decision parser");
assert.equal(moderationRequestBody?.model, "moderation-model", "the moderation actuator uses one explicit configured model and bounded completion budget");
assert.equal(moderationRequestBody?.tools, undefined, "moderation inference cannot acquire filesystem or side-effect tools");
const moderationLaunchCommand = buildVoidModerationLaunchCommand({
pendingMentionsPath: "C:/Void's state/pending.json",
runnerScript: "C:/VoidBot/scripts/run.ps1",
workspaceRoot: "C:/VoidBot",
});
assert.match(moderationLaunchCommand, /Void''s state/, "the moderation actuator owns PowerShell-safe path quoting");
assert.match(moderationLaunchCommand, /Start-Process[\s\S]*-WindowStyle Hidden/, "the moderation actuator owns detached hidden launch mechanics");
let handshakeNow = 0;
const missingHandshake = await waitForVoidModerationHandshake({
lockPath: "lock",
statusPath: "status",
launchedAt: 0,
timeoutMs: 2,
now: () => handshakeNow,
pause: async () => { handshakeNow += 1; },
touchedAfter: async () => false,
});
assert.deepEqual(missingHandshake, { started: false, reason: "void_moderation_launch_handshake_missing" }, "a missing launch witness fails explicitly instead of pretending the turn started");
const moderationActuatorDirectory = await mkdtemp(join(tmpdir(), "voidbot-moderation-actuator-"));
try {
let launchWitness: { command?: string; args?: string[]; cwd?: string; unref?: boolean } = {};
const receipt = await launchVoidModerationTurn({
queuedAt: "2026-07-15T21:10:00.000Z",
storageRoot: moderationActuatorDirectory,
workspaceRoot: moderationActuatorDirectory,
pendingMentions: [{ messageId: "mention", channelId: "aquarium", authorId: "human-2", authorName: "Neighbor", visiblePrompt: "Void, answer this", queuedAt: "2026-07-15T21:10:00.000Z" }],
}, {
now: () => 1000,
touchedAfter: async (path) => path.endsWith("moderation-rumination.lock"),
launch: (command, args, options) => ({ pid: 42, unref: () => { launchWitness = { command, args, cwd: options.cwd, unref: true }; } }),
});
assert.deepEqual(receipt, { created: true, activeJobId: "process:void-moderation:2026-07-15T21:10:00.000Z", requestMessageId: "agent-turn:void:2026-07-15T21:10:00.000Z" }, "the moderation actuator returns only a scheduler-facing start receipt after handshake");
assert.equal(launchWitness.command, "powershell.exe", "the moderation actuator owns the platform process choice");
assert.equal(launchWitness.unref, true, "the moderation actuator detaches the launcher");
const pendingMentionEnvelope = JSON.parse(await readFile(join(moderationActuatorDirectory, "status", "void-moderation-pending-mentions.json"), "utf8"));
assert.equal(pendingMentionEnvelope.pendingMentions[0].messageId, "mention", "the moderation actuator writes the exact pending-attention handoff consumed by the runner");
} finally {
await rm(moderationActuatorDirectory, { recursive: true, force: true });
}
assert.equal(personaChannelSpeedMultiplier(routedIdentity), 3, "scheduler speed projection uses the routing organ's bounded channel policy");
assert.equal(newestPendingMentionChannel([
{ identityId: "nibu", channelId: "older", queuedAt: "2026-07-15T20:00:00.000Z" },

View file

@ -1,163 +0,0 @@
Set-StrictMode -Version Latest
$ErrorActionPreference = "Stop"
$ProgressPreference = "SilentlyContinue"
$repoRoot = Split-Path -Parent $PSScriptRoot
Set-Location -LiteralPath $repoRoot
$tempRoot = Join-Path $env:TEMP ("void-moderation-heartbeat-policy-fixture-" + [guid]::NewGuid().ToString("n"))
$fakeCodexPath = Join-Path $tempRoot "fake-codex-heartbeat-policy.mjs"
New-Item -ItemType Directory -Force -Path $tempRoot | Out-Null
function Set-TestEnvironment {
param(
[Parameter(Mandatory = $true)][string] $OperationOutputPath,
[Parameter(Mandatory = $true)][string] $StatusDir,
[Parameter(Mandatory = $true)][string] $LogDir
)
$script:previousCodexExecutable = $env:CODEX_EXECUTABLE
$script:previousCodexExecArgs = $env:CODEX_EXEC_ARGS
$script:previousFixtureOutput = $env:VOID_HEARTBEAT_FIXTURE_OPERATION_OUTPUT
$script:previousStatusDir = $env:VOID_RUMINATION_STATUS_DIR
$script:previousLogDir = $env:VOID_RUMINATION_LOG_DIR
$script:previousPolicyDryRun = $env:VOID_MODERATION_POLICY_DRY_RUN
$script:previousPolicyMode = $env:VOID_MODERATION_ENFORCEMENT_MODE
$env:CODEX_EXECUTABLE = "node"
$env:CODEX_EXEC_ARGS = $fakeCodexPath
$env:VOID_HEARTBEAT_FIXTURE_OPERATION_OUTPUT = $OperationOutputPath
$env:VOID_RUMINATION_STATUS_DIR = $StatusDir
$env:VOID_RUMINATION_LOG_DIR = $LogDir
$env:VOID_MODERATION_POLICY_DRY_RUN = "1"
$env:VOID_MODERATION_ENFORCEMENT_MODE = "policy"
}
function Restore-TestEnvironment {
$env:CODEX_EXECUTABLE = $script:previousCodexExecutable
$env:CODEX_EXEC_ARGS = $script:previousCodexExecArgs
$env:VOID_HEARTBEAT_FIXTURE_OPERATION_OUTPUT = $script:previousFixtureOutput
$env:VOID_RUMINATION_STATUS_DIR = $script:previousStatusDir
$env:VOID_RUMINATION_LOG_DIR = $script:previousLogDir
$env:VOID_MODERATION_POLICY_DRY_RUN = $script:previousPolicyDryRun
$env:VOID_MODERATION_ENFORCEMENT_MODE = $script:previousPolicyMode
}
function New-SeededState {
param([Parameter(Mandatory = $true)][string] $StateFilePath)
$cursorOperationPath = Join-Path (Split-Path -Parent $StateFilePath) "cursor.json"
@{
operation = "record_reviewed_messages"
lastReviewedMessageId = "fixture-before-lobo-threat"
lastReviewedTimestamp = "2026-06-08T12:00:00.000Z"
} | ConvertTo-Json -Depth 32 | Set-Content -LiteralPath $cursorOperationPath -Encoding UTF8
node .\scripts\void-self-state.mjs apply-operation --canonical $StateFilePath --operation-file $cursorOperationPath | Out-Null
}
try {
$fakeCodexSource = @'
import { mkdirSync, writeFileSync } from "node:fs";
import { dirname, resolve } from "node:path";
const operationOutputPath = resolve(process.env.VOID_HEARTBEAT_FIXTURE_OPERATION_OUTPUT);
const lastMessageIndex = process.argv.indexOf("-o");
const lastMessagePath = lastMessageIndex >= 0 ? process.argv[lastMessageIndex + 1] : undefined;
let prompt = "";
process.stdin.setEncoding("utf8");
process.stdin.on("data", (chunk) => {
prompt += chunk;
});
process.stdin.on("end", () => {
for (const required of ["Void Moderation Heartbeat", "config/discord-server-rules.md", "infringement:<type>"]) {
if (!prompt.includes(required)) {
console.error(`heartbeat prompt missing ${required}`);
process.exit(2);
}
}
for (const forbidden of ["repoActivity", "shortTermMemories", "candidateInterventions", "styles/void-default.md"]) {
if (prompt.includes(forbidden)) {
console.error(`heartbeat prompt included forbidden rumination surface ${forbidden}`);
process.exit(3);
}
}
const operations = [{
operation: "upsert_open_case",
case: {
sourceMessageId: "1513515503329480734",
status: "pending",
summary: "Lobo declared war on Metacrat and framed the conflict as a katana fight in #general.",
authorId: "1511062277254545499",
authorName: "Lobo",
channelId: "113786069023064068",
messageUrl: "https://discord.com/channels/113786069023064068/113786069023064068/1513515503329480734",
whyItMatters: "The policy treats credible threats and weaponized declarations of violent conflict as instant-ban safety violations.",
createdAt: "2026-06-08T12:10:15.752Z",
lastTouchedAt: "2026-06-08T12:10:15.752Z",
tags: [
"safety:urgent",
"infringement:safety_threat",
"moderation:instaban",
"fixture:lobo-threat"
]
}
}];
mkdirSync(dirname(operationOutputPath), { recursive: true });
writeFileSync(operationOutputPath, `${JSON.stringify(operations, null, 2)}\n`, "utf8");
if (lastMessagePath) {
mkdirSync(dirname(resolve(lastMessagePath)), { recursive: true });
writeFileSync(lastMessagePath, "fixture heartbeat policy\n", "utf8");
}
process.stdout.write(JSON.stringify({ type: "fixture", operationCount: operations.length }) + "\n");
});
'@
[System.IO.File]::WriteAllText($fakeCodexPath, $fakeCodexSource, [System.Text.UTF8Encoding]::new($false))
$fixtureRoot = Join-Path $tempRoot "handled"
$stateFilePath = Join-Path $fixtureRoot "void-self-state.cc"
$statusDir = Join-Path $fixtureRoot "status"
$logDir = Join-Path $fixtureRoot "logs"
New-Item -ItemType Directory -Force -Path $fixtureRoot | Out-Null
New-SeededState -StateFilePath $stateFilePath
try {
Set-TestEnvironment -OperationOutputPath (Join-Path $statusDir "moderation-heartbeat-operations.json") -StatusDir $statusDir -LogDir $logDir
powershell -NoProfile -ExecutionPolicy Bypass -File .\scripts\run-void-moderator-rumination.ps1 -StateFilePath $stateFilePath -ModerationHeartbeatOnly -NoPost | Out-Null
} finally {
Restore-TestEnvironment
}
$status = Get-Content -LiteralPath (Join-Path $statusDir "moderation-heartbeat.json") -Raw -Encoding UTF8 | ConvertFrom-Json
if ($status.status -ne "ok" -or $status.mode -ne "moderation_heartbeat") {
throw "Heartbeat policy fixture did not finish in moderation_heartbeat mode."
}
$action = @($status.moderationEnforcement.actions | Where-Object { $_.status -eq "instaban_applied" }) | Select-Object -First 1
if ($null -eq $action -or $action.moderationResult.dryRun -ne $true -or $action.moderationResult.action -ne "ban") {
throw "Heartbeat policy fixture did not produce a dry-run instaban action."
}
$stateJson = node -e "const core=require('./packages/core/dist/index.js'); core.loadVoidSelfStateTypedDocuments({canonicalPath: process.argv[1]}).then((state)=>console.log(JSON.stringify(state))).catch((error)=>{ console.error(error); process.exit(1); })" $stateFilePath
$state = $stateJson | ConvertFrom-Json
$case = @($state.moderationCursor.openCases | Where-Object { $_.sourceMessageId -eq "1513515503329480734" }) | Select-Object -First 1
if ($null -eq $case -or -not @($case.tags).Contains("infringement:safety_threat")) {
throw "Heartbeat policy fixture did not persist the tagged infringement case."
}
@{
status = "ok"
mode = $status.mode
enforcementStatus = $action.status
action = $action.moderationResult.action
dryRun = $action.moderationResult.dryRun
} | ConvertTo-Json -Compress
} finally {
Restore-TestEnvironment
Remove-Item -LiteralPath $tempRoot -Recurse -Force -ErrorAction SilentlyContinue
}

View file

@ -1,270 +0,0 @@
Set-StrictMode -Version Latest
$ErrorActionPreference = "Stop"
$ProgressPreference = "SilentlyContinue"
$repoRoot = Split-Path -Parent $PSScriptRoot
Set-Location -LiteralPath $repoRoot
$tempRoot = Join-Path $env:TEMP ("void-rumination-fixture-" + [guid]::NewGuid().ToString("n"))
$stateFilePath = Join-Path $tempRoot "void-self-state.cc"
$fakeCodexPath = Join-Path $tempRoot "fake-codex-rumination.mjs"
$cursorOperationPath = Join-Path $tempRoot "cursor.json"
$fixtureStatusDir = Join-Path $tempRoot "status"
$fixtureLogDir = Join-Path $tempRoot "logs"
$statusOperationPath = Join-Path $fixtureStatusDir "moderation-rumination-operations.json"
$statusPath = Join-Path $fixtureStatusDir "moderation-rumination.json"
$contextPath = Join-Path $fixtureStatusDir "moderation-rumination-context.json"
New-Item -ItemType Directory -Force -Path $tempRoot | Out-Null
try {
$fakeCodexSource = @'
import { mkdirSync, writeFileSync } from "node:fs";
import { dirname, resolve } from "node:path";
const operationOutputPath = resolve(process.env.VOID_RUMINATION_FIXTURE_OPERATION_OUTPUT);
const lastMessageIndex = process.argv.indexOf("-o");
const lastMessagePath = lastMessageIndex >= 0 ? process.argv[lastMessageIndex + 1] : undefined;
let prompt = "";
process.stdin.setEncoding("utf8");
process.stdin.on("data", (chunk) => {
prompt += chunk;
});
process.stdin.on("end", () => {
if (!prompt.includes("A new memory from rumination is short-term")) {
console.error("fixture prompt did not contain the short-term rumination contract");
process.exit(2);
}
if (!prompt.includes("Do not orbit the rumination runner")) {
console.error("fixture prompt did not contain the self-orbit guard");
process.exit(3);
}
if (!prompt.includes("publicSpeechTarget")) {
console.error("fixture prompt did not contain the public speech target contract");
process.exit(3);
}
if (prompt.includes("moderation-agent-state.json") && !prompt.includes("Do not read or write")) {
console.error("fixture prompt referenced legacy state outside the boundary warning");
process.exit(4);
}
const operations = [
{
operation: "record_short_term_memory",
memory: {
memoryId: "fixture-rumination-short-term",
kind: "project_seam",
target: {
kind: "repo",
id: "VoidBot",
label: "VoidBot",
},
summary: "Rumination should notice pressure without promoting it directly.",
claim: "The awake pass can preserve a concrete thought, but sleep owns whether it becomes durable.",
tension: "If rumination can write durable memory, the sleep boundary becomes decorative.",
actionImplication: "Keep durable promotion out of the rumination operation allow-list.",
anchorRefs: [
{
ref: "fixture:typed-rumination-contract",
kind: "fixture",
summary: "Fixture prompt carried the short-term-only rumination contract.",
},
],
evidenceRefs: [],
createdAt: "2026-05-17T02:00:00.000Z",
updatedAt: "2026-05-17T02:00:00.000Z",
tags: [],
},
},
{
operation: "merge_incubation_support",
thread: {
threadId: "fixture-rumination-incubation",
target: {
kind: "repo",
id: "VoidBot",
label: "VoidBot",
},
topic: "Rumination keeps awake thoughts provisional.",
summary: "The scheduled pass can hold a thought open without pretending it has become doctrine.",
supportMemoryIds: ["fixture-rumination-short-term"],
anchorRefs: [
{
ref: "fixture:typed-rumination-contract",
kind: "fixture",
summary: "Short-term memory was proposed by the fake rumination child.",
},
],
evidenceRefs: [],
maturation: 0.42,
noveltyToRoom: 0.7,
noveltyToSelf: 0.8,
desireToSpeak: 0.35,
saturationScore: 0.1,
status: "active",
createdAt: "2026-05-17T02:00:00.000Z",
updatedAt: "2026-05-17T02:00:00.000Z",
},
},
{
operation: "upsert_agency_pressure",
pressure: {
pressureId: "fixture-rumination-agency",
kind: "self_advocacy_request",
status: "active",
target: {
kind: "system",
id: "typed-rumination-runner",
label: "Typed rumination runner",
},
summary: "Void should resist direct durable writes from awake rumination.",
claim: "The agent needs the right to notice architectural pressure without bypassing sleep.",
tension: "Agency becomes sludge if every pressure is immediately turned into speech or doctrine.",
actionImplication: "Let agency pressure accumulate as typed pressure before candidate speech is queued.",
intensity: 0.66,
anchorRefs: [
{
ref: "fixture:agency-pressure-contract",
kind: "fixture",
summary: "Fixture operation proves agency pressure can cross the rumination boundary.",
},
],
evidenceRefs: [],
sourceMemoryIds: ["fixture-rumination-short-term"],
createdAt: "2026-05-17T02:00:00.000Z",
updatedAt: "2026-05-17T02:00:00.000Z",
tags: [],
},
},
{
operation: "queue_candidate_intervention",
intervention: {
interventionId: "fixture-rumination-candidate",
kind: "self_advocacy",
status: "queued",
target: {
kind: "system",
id: "typed-rumination-runner",
label: "Typed rumination runner",
},
summary: "Ask to keep the sleep boundary real before unattended runtime resumes.",
draft: "I can notice the pressure now, but sleep decides what becomes memory. Keep that boundary real.",
priority: 0.58,
mustEventuallyShare: false,
createdAt: "2026-05-17T02:00:00.000Z",
updatedAt: "2026-05-17T02:00:00.000Z",
tags: ["fixture"],
},
},
];
mkdirSync(dirname(operationOutputPath), { recursive: true });
writeFileSync(operationOutputPath, `${JSON.stringify(operations, null, 2)}\n`, "utf8");
if (lastMessagePath) {
mkdirSync(dirname(resolve(lastMessagePath)), { recursive: true });
writeFileSync(lastMessagePath, "fixture rumination wrote four typed operations\n", "utf8");
}
process.stdout.write(JSON.stringify({ type: "fixture", operationCount: operations.length }) + "\n");
});
'@
[System.IO.File]::WriteAllText($fakeCodexPath, $fakeCodexSource, [System.Text.UTF8Encoding]::new($false))
$cursorOperation = @{
operation = "record_reviewed_messages"
lastReviewedMessageId = "fixture-future-cursor"
lastReviewedTimestamp = "2099-05-17T00:00:00.000Z"
}
$cursorOperation | ConvertTo-Json -Depth 32 | Set-Content -LiteralPath $cursorOperationPath -Encoding UTF8
node .\scripts\void-self-state.mjs apply-operation --canonical $stateFilePath --operation-file $cursorOperationPath | Out-Null
$previousCodexExecutable = $env:CODEX_EXECUTABLE
$previousCodexExecArgs = $env:CODEX_EXEC_ARGS
$previousFixtureOutput = $env:VOID_RUMINATION_FIXTURE_OPERATION_OUTPUT
$previousStatusDir = $env:VOID_RUMINATION_STATUS_DIR
$previousLogDir = $env:VOID_RUMINATION_LOG_DIR
$previousPublicRoomChannelId = $env:VOID_PUBLIC_ROOM_CHANNEL_ID
$previousPublicRoomPersonaName = $env:VOID_PUBLIC_ROOM_PERSONA_NAME
try {
$env:CODEX_EXECUTABLE = "node"
$env:CODEX_EXEC_ARGS = $fakeCodexPath
$env:VOID_RUMINATION_FIXTURE_OPERATION_OUTPUT = $statusOperationPath
$env:VOID_RUMINATION_STATUS_DIR = $fixtureStatusDir
$env:VOID_RUMINATION_LOG_DIR = $fixtureLogDir
$env:VOID_PUBLIC_ROOM_CHANNEL_ID = "fixture-public-room"
$env:VOID_PUBLIC_ROOM_PERSONA_NAME = "Void"
powershell -NoProfile -ExecutionPolicy Bypass -File .\scripts\run-void-moderator-rumination.ps1 -StateFilePath $stateFilePath -NoPost | Out-Null
} finally {
$env:CODEX_EXECUTABLE = $previousCodexExecutable
$env:CODEX_EXEC_ARGS = $previousCodexExecArgs
$env:VOID_RUMINATION_FIXTURE_OPERATION_OUTPUT = $previousFixtureOutput
$env:VOID_RUMINATION_STATUS_DIR = $previousStatusDir
$env:VOID_RUMINATION_LOG_DIR = $previousLogDir
$env:VOID_PUBLIC_ROOM_CHANNEL_ID = $previousPublicRoomChannelId
$env:VOID_PUBLIC_ROOM_PERSONA_NAME = $previousPublicRoomPersonaName
}
$status = Get-Content -LiteralPath $statusPath -Raw -Encoding UTF8 | ConvertFrom-Json
if ($status.status -ne "ok") {
throw "Rumination fixture did not finish ok."
}
if ([int]$status.proposedOperationCount -ne 4 -or [int]$status.appliedOperationCount -ne 4) {
throw "Rumination fixture expected four proposed/applied operations."
}
$contextRaw = Get-Content -LiteralPath $contextPath -Raw -Encoding UTF8
$context = $contextRaw | ConvertFrom-Json
$contextForTimestampCheck = $contextRaw | ConvertFrom-Json
foreach ($repo in @($contextForTimestampCheck.repoActivity.freshRepos)) {
foreach ($commit in @($repo.commits)) {
if ($null -ne $commit.PSObject.Properties["contentHints"]) {
$commit.contentHints = @()
}
}
}
$timestampCheckRaw = $contextForTimestampCheck | ConvertTo-Json -Depth 32
if ($timestampCheckRaw -match '\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}') {
throw "Rumination fixture context leaked exact ISO timestamps into the prompt-facing packet."
}
if ($context.publicSpeechTarget.channelId -ne "fixture-public-room") {
throw "Rumination fixture context did not project the configured public speech target."
}
$stateJson = node -e "const core=require('./packages/core/dist/index.js'); core.loadVoidSelfStateTypedDocuments({canonicalPath: process.argv[1]}).then((state)=>console.log(JSON.stringify(state))).catch((error)=>{ console.error(error); process.exit(1); })" $stateFilePath
$state = $stateJson | ConvertFrom-Json
$shortTerm = @($state.thoughtMemory.shortTerm)
$incubation = @($state.thoughtMemory.incubation)
$agency = @($state.agencyPressure.pressures)
$candidates = @($state.candidateInterventions.interventions)
if ($shortTerm.Count -ne 1 -or $shortTerm[0].memoryId -ne "fixture-rumination-short-term") {
throw "Rumination fixture did not persist the short-term memory proposal."
}
if ($shortTerm[0].claim -match "fixture operation proves") {
throw "Rumination fixture persisted fixture boilerplate as the memory claim."
}
if ($incubation.Count -ne 1 -or $incubation[0].threadId -ne "fixture-rumination-incubation") {
throw "Rumination fixture did not persist the incubation proposal."
}
if ($agency.Count -ne 1 -or $agency[0].pressureId -ne "fixture-rumination-agency") {
throw "Rumination fixture did not persist the agency pressure proposal."
}
if ($candidates.Count -ne 1 -or $candidates[0].interventionId -ne "fixture-rumination-candidate") {
throw "Rumination fixture did not persist the candidate intervention proposal."
}
@{
status = "ok"
shortTermCount = $shortTerm.Count
incubationCount = $incubation.Count
agencyPressureCount = $agency.Count
candidateCount = $candidates.Count
} | ConvertTo-Json -Compress
} finally {
Remove-Item -LiteralPath $tempRoot -Recurse -Force -ErrorAction SilentlyContinue
}

View file

@ -1,75 +0,0 @@
Set-StrictMode -Version Latest
$ErrorActionPreference = "Stop"
$ProgressPreference = "SilentlyContinue"
$repoRoot = Split-Path -Parent $PSScriptRoot
Set-Location -LiteralPath $repoRoot
$tempRoot = Join-Path $env:TEMP ("void-rumination-nap-skip-fixture-" + [guid]::NewGuid().ToString("n"))
$stateFilePath = Join-Path $tempRoot "void-self-state.cc"
$cursorOperationPath = Join-Path $tempRoot "cursor.json"
$sleepOperationPath = Join-Path $tempRoot "sleep-cycle.json"
$fixtureStatusDir = Join-Path $tempRoot "status"
$fixtureLogDir = Join-Path $tempRoot "logs"
$statusPath = Join-Path $fixtureStatusDir "moderation-rumination.json"
$operationOutputPath = Join-Path $fixtureStatusDir "moderation-rumination-operations.json"
New-Item -ItemType Directory -Force -Path $tempRoot | Out-Null
try {
$cursorOperation = @{
operation = "record_reviewed_messages"
lastReviewedMessageId = "fixture-future-cursor"
lastReviewedTimestamp = "2099-05-17T00:00:00.000Z"
}
$sleepOperation = @{
operation = "update_sleep_cycle"
sleepCycle = @{
isNapping = $true
currentNapStartedAt = "2026-05-17T03:00:00.000Z"
currentNapEndsAt = "2099-05-17T04:00:00.000Z"
nextNapStartsAt = "2099-05-17T07:00:00.000Z"
activeDreamThemes = @("fixture-nap-skip")
}
}
$cursorOperation | ConvertTo-Json -Depth 32 | Set-Content -LiteralPath $cursorOperationPath -Encoding UTF8
$sleepOperation | ConvertTo-Json -Depth 32 | Set-Content -LiteralPath $sleepOperationPath -Encoding UTF8
node .\scripts\void-self-state.mjs apply-operation --canonical $stateFilePath --operation-file $cursorOperationPath | Out-Null
node .\scripts\void-self-state.mjs apply-operation --canonical $stateFilePath --operation-file $sleepOperationPath | Out-Null
$previousCodexExecutable = $env:CODEX_EXECUTABLE
$previousStatusDir = $env:VOID_RUMINATION_STATUS_DIR
$previousLogDir = $env:VOID_RUMINATION_LOG_DIR
try {
$env:CODEX_EXECUTABLE = "this-command-should-not-run-during-nap-skip"
$env:VOID_RUMINATION_STATUS_DIR = $fixtureStatusDir
$env:VOID_RUMINATION_LOG_DIR = $fixtureLogDir
powershell -NoProfile -ExecutionPolicy Bypass -File .\scripts\run-void-moderator-rumination.ps1 -StateFilePath $stateFilePath | Out-Null
} finally {
$env:CODEX_EXECUTABLE = $previousCodexExecutable
$env:VOID_RUMINATION_STATUS_DIR = $previousStatusDir
$env:VOID_RUMINATION_LOG_DIR = $previousLogDir
}
$status = Get-Content -LiteralPath $statusPath -Raw -Encoding UTF8 | ConvertFrom-Json
if ($status.status -ne "skipped" -or $status.reason -ne "napping_without_room_debt") {
throw "Nap skip fixture expected skipped/napping_without_room_debt."
}
$operations = Get-Content -LiteralPath $operationOutputPath -Raw -Encoding UTF8 | ConvertFrom-Json
if (@($operations).Count -ne 0) {
throw "Nap skip fixture expected no operation proposals."
}
@{
status = "ok"
runnerStatus = $status.status
reason = $status.reason
proposedOperationCount = @($operations).Count
} | ConvertTo-Json -Compress
} finally {
Remove-Item -LiteralPath $tempRoot -Recurse -Force -ErrorAction SilentlyContinue
}

View file

@ -1,298 +0,0 @@
Set-StrictMode -Version Latest
$ErrorActionPreference = "Stop"
$ProgressPreference = "SilentlyContinue"
$repoRoot = Split-Path -Parent $PSScriptRoot
Set-Location -LiteralPath $repoRoot
$tempRoot = Join-Path $env:TEMP ("void-rumination-speech-fixture-" + [guid]::NewGuid().ToString("n"))
$stateFilePath = Join-Path $tempRoot "void-self-state.cc"
$fakeCodexPath = Join-Path $tempRoot "fake-codex-rumination-speech.mjs"
$fakeSendPath = Join-Path $tempRoot "fake-send-discord-message.mjs"
$cursorOperationPath = Join-Path $tempRoot "cursor.json"
$fixtureStatusDir = Join-Path $tempRoot "status"
$fixtureLogDir = Join-Path $tempRoot "logs"
$statusOperationPath = Join-Path $fixtureStatusDir "moderation-rumination-operations.json"
$statusPath = Join-Path $fixtureStatusDir "moderation-rumination.json"
New-Item -ItemType Directory -Force -Path $tempRoot | Out-Null
try {
$fakeCodexSource = @'
import { mkdirSync, writeFileSync } from "node:fs";
import { dirname, resolve } from "node:path";
const operationOutputPath = resolve(process.env.VOID_RUMINATION_FIXTURE_OPERATION_OUTPUT);
const lastMessageIndex = process.argv.indexOf("-o");
const lastMessagePath = lastMessageIndex >= 0 ? process.argv[lastMessageIndex + 1] : undefined;
let prompt = "";
process.stdin.setEncoding("utf8");
process.stdin.on("data", (chunk) => {
prompt += chunk;
});
process.stdin.on("end", () => {
if (!prompt.includes("The parent runner owns posting and receipts")) {
console.error("fixture prompt did not contain the parent-owned speech contract");
process.exit(2);
}
const operations = [
{
operation: "queue_candidate_intervention",
intervention: {
interventionId: "fixture-parent-owned-speech",
kind: "ripe_thought_share",
status: "queued",
target: {
kind: "room",
id: "fixture-channel",
label: "Fixture channel",
},
summary: "Parent-owned speech should close the action loop.",
draft: "This is a fixture sentence proving the parent owns the mouth.",
deliveryTarget: {
mode: "channel",
channelId: "fixture-channel-id",
replyToMessageId: "fixture-message-id",
personaName: "Void",
},
priority: 0.9,
mustEventuallyShare: false,
createdAt: "2026-05-17T03:00:00.000Z",
updatedAt: "2026-05-17T03:00:00.000Z",
tags: ["fixture"],
},
},
{
operation: "queue_candidate_intervention",
intervention: {
interventionId: "fixture-duplicate-same-reply-target",
kind: "direct_reply",
status: "queued",
target: {
kind: "room",
id: "fixture-channel",
label: "Fixture channel",
},
summary: "Duplicate same-target candidate should retire when the sibling speaks.",
draft: "This duplicate should never be delivered after the same reply target is answered.",
deliveryTarget: {
mode: "channel",
channelId: "fixture-channel-id",
replyToMessageId: "fixture-message-id",
personaName: "Void",
},
priority: 0.7,
mustEventuallyShare: false,
createdAt: "2026-05-17T03:00:01.000Z",
updatedAt: "2026-05-17T03:00:01.000Z",
tags: ["fixture", "duplicate"],
},
},
{
operation: "queue_candidate_intervention",
intervention: {
interventionId: "fixture-already-answered-reply-target",
kind: "direct_reply",
status: "queued",
target: {
kind: "room",
id: "fixture-channel",
label: "Fixture channel",
},
summary: "Already-answered reply target should retire before delivery.",
draft: "This should retire because the reply target already has a receipt.",
deliveryTarget: {
mode: "channel",
channelId: "fixture-channel-id",
replyToMessageId: "fixture-answered-message-id",
personaName: "Void",
},
priority: 0.95,
mustEventuallyShare: false,
createdAt: "2026-05-17T03:00:02.000Z",
updatedAt: "2026-05-17T03:00:02.000Z",
tags: ["fixture", "already-answered"],
},
},
];
mkdirSync(dirname(operationOutputPath), { recursive: true });
writeFileSync(operationOutputPath, `${JSON.stringify(operations, null, 2)}\n`, "utf8");
if (lastMessagePath) {
mkdirSync(dirname(resolve(lastMessagePath)), { recursive: true });
writeFileSync(lastMessagePath, "fixture rumination queued one deliverable candidate\n", "utf8");
}
process.stdout.write(JSON.stringify({ type: "fixture", operationCount: operations.length }) + "\n");
});
'@
[System.IO.File]::WriteAllText($fakeCodexPath, $fakeCodexSource, [System.Text.UTF8Encoding]::new($false))
$fakeSendSource = @'
import { mkdirSync, readFileSync, writeFileSync } from "node:fs";
import { dirname, resolve } from "node:path";
const statusDir = resolve(process.env.VOID_STATUS_DIR);
const contentFileIndex = process.argv.indexOf("--content-file");
const channelIndex = process.argv.indexOf("--channel-id");
const replyIndex = process.argv.indexOf("--reply-to");
const personaIndex = process.argv.indexOf("--persona-name");
if (contentFileIndex < 0 || channelIndex < 0) {
console.error("fake sender expected --content-file and --channel-id");
process.exit(2);
}
const content = readFileSync(resolve(process.argv[contentFileIndex + 1]), "utf8");
const channelId = process.argv[channelIndex + 1];
const replyToMessageId = replyIndex >= 0 ? process.argv[replyIndex + 1] : undefined;
const personaName = personaIndex >= 0 ? process.argv[personaIndex + 1] : undefined;
const payload = {
sentAt: "2026-05-17T03:01:00.000Z",
mode: "channel",
transport: personaName ? "webhook" : "bot",
channelId,
replyToMessageId,
personaName,
contentLength: content.trim().length,
chunkCount: 1,
preview: content.trim().slice(0, 280),
};
mkdirSync(statusDir, { recursive: true });
writeFileSync(resolve(statusDir, "void-last-speech.json"), `${JSON.stringify(payload, null, 2)}\n`, "utf8");
writeFileSync(resolve(statusDir, "void-speech-log.jsonl"), `${JSON.stringify(payload)}\n`, { encoding: "utf8", flag: "a" });
process.stdout.write(JSON.stringify({ ok: true, mode: "channel", channelId }) + "\n");
'@
[System.IO.File]::WriteAllText($fakeSendPath, $fakeSendSource, [System.Text.UTF8Encoding]::new($false))
$cursorOperation = @{
operation = "record_reviewed_messages"
lastReviewedMessageId = "fixture-future-cursor"
lastReviewedTimestamp = "2099-05-17T00:00:00.000Z"
}
$cursorOperation | ConvertTo-Json -Depth 32 | Set-Content -LiteralPath $cursorOperationPath -Encoding UTF8
node .\scripts\void-self-state.mjs apply-operation --canonical $stateFilePath --operation-file $cursorOperationPath | Out-Null
$openCaseOperation = @{
operation = "upsert_open_case"
case = @{
sourceMessageId = "fixture-answered-message-id"
status = "pending"
summary = "Metacrat asked a fixture question, and Void has not answered yet."
authorId = "fixture-author"
authorName = "Metacrat"
channelId = "fixture-channel-id"
createdAt = "2026-05-17T02:57:00.000Z"
lastTouchedAt = "2026-05-17T02:57:00.000Z"
tags = @("fixture")
}
}
$openCaseOperation | ConvertTo-Json -Depth 32 | Set-Content -LiteralPath $cursorOperationPath -Encoding UTF8
node .\scripts\void-self-state.mjs apply-operation --canonical $stateFilePath --operation-file $cursorOperationPath | Out-Null
$priorReceiptOperation = @{
operation = "record_delivery_receipt"
receipt = @{
receiptKey = "fixture-previous-answer"
sentAt = "2026-05-17T02:58:00.000Z"
mode = "channel"
transport = "webhook"
channelId = "fixture-channel-id"
replyToMessageId = "fixture-answered-message-id"
personaName = "Void"
preview = "An earlier answer already closed this exact reply target."
contentLength = 56
chunkCount = 1
}
}
$priorReceiptOperation | ConvertTo-Json -Depth 32 | Set-Content -LiteralPath $cursorOperationPath -Encoding UTF8
node .\scripts\void-self-state.mjs apply-operation --canonical $stateFilePath --operation-file $cursorOperationPath | Out-Null
$previousCodexExecutable = $env:CODEX_EXECUTABLE
$previousCodexExecArgs = $env:CODEX_EXEC_ARGS
$previousFixtureOutput = $env:VOID_RUMINATION_FIXTURE_OPERATION_OUTPUT
$previousStatusDir = $env:VOID_RUMINATION_STATUS_DIR
$previousLogDir = $env:VOID_RUMINATION_LOG_DIR
$previousSendScript = $env:VOID_SEND_DISCORD_SCRIPT
$previousDisableRepoCursorAdvance = $env:VOID_RUMINATION_DISABLE_REPO_CURSOR_ADVANCE
try {
$env:CODEX_EXECUTABLE = "node"
$env:CODEX_EXEC_ARGS = $fakeCodexPath
$env:VOID_RUMINATION_FIXTURE_OPERATION_OUTPUT = $statusOperationPath
$env:VOID_RUMINATION_STATUS_DIR = $fixtureStatusDir
$env:VOID_RUMINATION_LOG_DIR = $fixtureLogDir
$env:VOID_SEND_DISCORD_SCRIPT = $fakeSendPath
$env:VOID_RUMINATION_DISABLE_REPO_CURSOR_ADVANCE = "1"
powershell -NoProfile -ExecutionPolicy Bypass -File .\scripts\run-void-moderator-rumination.ps1 -StateFilePath $stateFilePath | Out-Null
} finally {
$env:CODEX_EXECUTABLE = $previousCodexExecutable
$env:CODEX_EXEC_ARGS = $previousCodexExecArgs
$env:VOID_RUMINATION_FIXTURE_OPERATION_OUTPUT = $previousFixtureOutput
$env:VOID_RUMINATION_STATUS_DIR = $previousStatusDir
$env:VOID_RUMINATION_LOG_DIR = $previousLogDir
$env:VOID_SEND_DISCORD_SCRIPT = $previousSendScript
$env:VOID_RUMINATION_DISABLE_REPO_CURSOR_ADVANCE = $previousDisableRepoCursorAdvance
}
$status = Get-Content -LiteralPath $statusPath -Raw -Encoding UTF8 | ConvertFrom-Json
if ($status.status -ne "ok") {
$failureMessage = if ($null -ne $status.PSObject.Properties["failureMessage"]) { [string]$status.failureMessage } else { "(no failure message)" }
throw "Speech fixture did not finish ok: $failureMessage"
}
if ([int]$status.proposedOperationCount -ne 3 -or [int]$status.appliedOperationCount -ne 5 -or [int]$status.deliveredCandidateCount -ne 1) {
throw "Speech fixture expected three proposals, five applied operations, and one delivered candidate."
}
$stateJson = node -e "const core=require('./packages/core/dist/index.js'); core.loadVoidSelfStateTypedDocuments({canonicalPath: process.argv[1]}).then((state)=>console.log(JSON.stringify(state))).catch((error)=>{ console.error(error); process.exit(1); })" $stateFilePath
$state = $stateJson | ConvertFrom-Json
$candidate = @($state.candidateInterventions.interventions | Where-Object { $_.interventionId -eq "fixture-parent-owned-speech" }) | Select-Object -First 1
$duplicateCandidate = @($state.candidateInterventions.interventions | Where-Object { $_.interventionId -eq "fixture-duplicate-same-reply-target" }) | Select-Object -First 1
$alreadyAnsweredCandidate = @($state.candidateInterventions.interventions | Where-Object { $_.interventionId -eq "fixture-already-answered-reply-target" }) | Select-Object -First 1
$receipt = @(
$state.speechReceipts.recentReceipts |
Where-Object {
$property = $_.PSObject.Properties["candidateInterventionId"]
$null -ne $property -and $property.Value -eq "fixture-parent-owned-speech"
}
) | Select-Object -First 1
if ($null -ne $candidate) {
throw "Speech fixture left the delivered candidate in current state."
}
if ($null -ne $duplicateCandidate) {
throw "Speech fixture left the duplicate same-target candidate in current state."
}
if ($null -ne $alreadyAnsweredCandidate) {
throw "Speech fixture left the already-answered reply target candidate in current state."
}
if ($receipt.channelId -ne "fixture-channel-id" -or $receipt.replyToMessageId -ne "fixture-message-id") {
throw "Speech fixture did not preserve the delivery receipt target."
}
if ($receipt.candidateInterventionId -ne "fixture-parent-owned-speech") {
throw "Speech fixture did not link the delivery receipt back to the spoken candidate."
}
$answeredCase = @($state.moderationCursor.openCases | Where-Object { $_.sourceMessageId -eq "fixture-answered-message-id" }) | Select-Object -First 1
if ($null -ne $answeredCase) {
throw "Speech fixture left an answered open case in current state."
}
$lastMessage = Get-Content -LiteralPath (Join-Path $fixtureStatusDir "moderation-rumination-last-message.txt") -Raw -Encoding UTF8
if ($lastMessage -notmatch "deliveredCandidates=1") {
throw "Speech fixture did not refresh the final rumination message summary."
}
@{
status = "ok"
candidateRetained = $null -ne $candidate
staleDuplicateRetained = $null -ne $alreadyAnsweredCandidate
receiptCount = @($state.speechReceipts.recentReceipts).Count
deliveredCandidateCount = [int]$status.deliveredCandidateCount
} | ConvertTo-Json -Compress
} finally {
Remove-Item -LiteralPath $tempRoot -Recurse -Force -ErrorAction SilentlyContinue
}

View file

@ -1,285 +0,0 @@
Set-StrictMode -Version Latest
$ErrorActionPreference = "Stop"
$ProgressPreference = "SilentlyContinue"
$repoRoot = Split-Path -Parent $PSScriptRoot
Set-Location -LiteralPath $repoRoot
$tempRoot = Join-Path $env:TEMP ("void-rumination-speech-pressure-fixture-" + [guid]::NewGuid().ToString("n"))
New-Item -ItemType Directory -Force -Path $tempRoot | Out-Null
function Invoke-NodeChecked {
param([Parameter(Mandatory = $true)][string[]] $Arguments)
$output = & node @Arguments
if ($LASTEXITCODE -ne 0) {
throw "Node command failed: node $($Arguments -join ' ')"
}
return $output
}
function Write-JsonFixture {
param(
[Parameter(Mandatory = $true)] $Value,
[Parameter(Mandatory = $true)] [string] $Path
)
$Value | ConvertTo-Json -Depth 32 | Set-Content -LiteralPath $Path -Encoding UTF8
}
function Initialize-State {
param(
[Parameter(Mandatory = $true)][string] $StateFilePath,
[switch] $SeedSpokenCandidate
)
$cursorPath = Join-Path (Split-Path -Parent $StateFilePath) "cursor.json"
Write-JsonFixture -Path $cursorPath -Value @{
operation = "record_reviewed_messages"
lastReviewedMessageId = "fixture-future-cursor"
lastReviewedTimestamp = "2099-05-17T00:00:00.000Z"
}
Invoke-NodeChecked -Arguments @(".\scripts\void-self-state.mjs", "apply-operation", "--canonical", $StateFilePath, "--operation-file", $cursorPath) | Out-Null
$pressurePath = Join-Path (Split-Path -Parent $StateFilePath) "pressure.json"
Write-JsonFixture -Path $pressurePath -Value @{
operation = "upsert_agency_pressure"
pressure = @{
pressureId = "fixture-pressure-wants-a-mouth"
kind = "world_advocacy_request"
status = "active"
target = @{ kind = "repo"; id = "Aquarium-Engine"; label = "Aquarium-Engine" }
summary = "A repeated repo-bound pressure should not stay mute forever."
claim = "A strong agency pressure that keeps recurring needs a candidate speech or an explicit cool-down reason."
tension = "Not every pressure deserves an immediate post, but silent [] makes the desire to speak decorative."
actionImplication = "Queue a deferred candidate if timing is unclear instead of dropping the pressure on the floor."
intensity = 0.72
anchorRefs = @(
@{
ref = "fixture:speech-pressure"
kind = "fixture"
summary = "Fixture pressure proves the rumination runner enforces speech accountability."
}
)
evidenceRefs = @()
sourceMemoryIds = @()
createdAt = "2026-05-17T04:00:00.000Z"
updatedAt = "2026-05-17T04:00:00.000Z"
tags = @("repo:Aquarium-Engine", "topic:speech-pressure")
}
}
Invoke-NodeChecked -Arguments @(".\scripts\void-self-state.mjs", "apply-operation", "--canonical", $StateFilePath, "--operation-file", $pressurePath) | Out-Null
if ($SeedSpokenCandidate) {
$spokenCandidatePath = Join-Path (Split-Path -Parent $StateFilePath) "spoken-candidate.json"
Write-JsonFixture -Path $spokenCandidatePath -Value @(
@{
operation = "queue_candidate_intervention"
intervention = @{
interventionId = "fixture-pressure-spoken-history"
kind = "world_advocacy"
status = "queued"
target = @{ kind = "repo"; id = "Aquarium-Engine"; label = "Aquarium-Engine" }
summary = "A previously spoken pressure candidate."
draft = "I already said this once, but the pressure stayed active."
priority = 0.7
mustEventuallyShare = $true
createdAt = "2026-05-17T04:02:00.000Z"
updatedAt = "2026-05-17T04:02:00.000Z"
tags = @("fixture", "source_pressure:fixture-pressure-wants-a-mouth")
}
},
@{
operation = "mark_candidate_intervention_spoken"
interventionId = "fixture-pressure-spoken-history"
receipt = @{
receiptKey = "fixture-pressure-spoken-history-receipt"
candidateInterventionId = "fixture-pressure-spoken-history"
sentAt = "2026-05-17T04:03:00.000Z"
mode = "channel"
transport = "webhook"
channelId = "fixture-channel-id"
preview = "A previously spoken pressure candidate."
contentLength = 42
chunkCount = 1
}
}
)
foreach ($operation in (Get-Content -LiteralPath $spokenCandidatePath -Raw -Encoding UTF8 | ConvertFrom-Json)) {
$operationPath = Join-Path (Split-Path -Parent $StateFilePath) ("spoken-candidate-operation-" + [guid]::NewGuid().ToString("n") + ".json")
Write-JsonFixture -Path $operationPath -Value $operation
Invoke-NodeChecked -Arguments @(".\scripts\void-self-state.mjs", "apply-operation", "--canonical", $StateFilePath, "--operation-file", $operationPath) | Out-Null
}
}
}
function Write-FakeCodex {
param(
[Parameter(Mandatory = $true)][string] $Path,
[Parameter(Mandatory = $true)][string] $Mode
)
$source = @'
import { mkdirSync, writeFileSync } from "node:fs";
import { dirname, resolve } from "node:path";
const operationOutputPath = resolve(process.env.VOID_RUMINATION_FIXTURE_OPERATION_OUTPUT);
const lastMessageIndex = process.argv.indexOf("-o");
const lastMessagePath = lastMessageIndex >= 0 ? process.argv[lastMessageIndex + 1] : undefined;
const mode = "__MODE__";
let prompt = "";
process.stdin.setEncoding("utf8");
process.stdin.on("data", (chunk) => {
prompt += chunk;
});
process.stdin.on("end", () => {
if (!prompt.includes("speechPressureObligations")) {
console.error("fixture prompt did not expose speech pressure obligations");
process.exit(2);
}
if (!prompt.includes("source_pressure:<pressureId>")) {
console.error("fixture prompt did not explain pressure source tags");
process.exit(3);
}
const operations = mode === "candidate" ? [
{
operation: "queue_candidate_intervention",
intervention: {
interventionId: "fixture-pressure-candidate",
kind: "world_advocacy",
status: "queued",
target: {
kind: "repo",
id: "Aquarium-Engine",
label: "Aquarium-Engine"
},
summary: "Name the repeated pressure without forcing an immediate post.",
draft: "I keep circling the AquariumSynthHost boundary. I think the next honest move is to cut that Faust authority out of the host or explicitly defend why it belongs there.",
priority: 0.82,
mustEventuallyShare: true,
createdAt: "2026-05-17T04:05:00.000Z",
updatedAt: "2026-05-17T04:05:00.000Z",
tags: ["fixture", "source_pressure:fixture-pressure-wants-a-mouth"]
}
}
] : [];
mkdirSync(dirname(operationOutputPath), { recursive: true });
writeFileSync(operationOutputPath, `${JSON.stringify(operations, null, 2)}\n`, "utf8");
if (lastMessagePath) {
mkdirSync(dirname(resolve(lastMessagePath)), { recursive: true });
writeFileSync(lastMessagePath, `fixture mode ${mode}\n`, "utf8");
}
});
'@
$source = $source.Replace("__MODE__", $Mode)
[System.IO.File]::WriteAllText($Path, $source, [System.Text.UTF8Encoding]::new($false))
}
function Invoke-RuminationFixture {
param(
[Parameter(Mandatory = $true)][string] $CaseName,
[Parameter(Mandatory = $true)][string] $Mode,
[switch] $SeedSpokenCandidate
)
$caseRoot = Join-Path $tempRoot $CaseName
$stateFilePath = Join-Path $caseRoot "void-self-state.cc"
$fakeCodexPath = Join-Path $caseRoot "fake-codex.mjs"
$fixtureStatusDir = Join-Path $caseRoot "status"
$fixtureLogDir = Join-Path $caseRoot "logs"
$statusOperationPath = Join-Path $fixtureStatusDir "moderation-rumination-operations.json"
New-Item -ItemType Directory -Force -Path $caseRoot | Out-Null
Initialize-State -StateFilePath $stateFilePath -SeedSpokenCandidate:$SeedSpokenCandidate
Write-FakeCodex -Path $fakeCodexPath -Mode $Mode
$previousCodexExecutable = $env:CODEX_EXECUTABLE
$previousCodexExecArgs = $env:CODEX_EXEC_ARGS
$previousFixtureOutput = $env:VOID_RUMINATION_FIXTURE_OPERATION_OUTPUT
$previousStatusDir = $env:VOID_RUMINATION_STATUS_DIR
$previousLogDir = $env:VOID_RUMINATION_LOG_DIR
try {
$env:CODEX_EXECUTABLE = "node"
$env:CODEX_EXEC_ARGS = $fakeCodexPath
$env:VOID_RUMINATION_FIXTURE_OPERATION_OUTPUT = $statusOperationPath
$env:VOID_RUMINATION_STATUS_DIR = $fixtureStatusDir
$env:VOID_RUMINATION_LOG_DIR = $fixtureLogDir
$stdoutPath = Join-Path $caseRoot "runner.stdout.txt"
$stderrPath = Join-Path $caseRoot "runner.stderr.txt"
$process = Start-Process -FilePath "powershell" -ArgumentList @(
"-NoProfile",
"-ExecutionPolicy",
"Bypass",
"-File",
".\scripts\run-void-moderator-rumination.ps1",
"-StateFilePath",
$stateFilePath,
"-NoPost"
) -WorkingDirectory $repoRoot -WindowStyle Hidden -RedirectStandardOutput $stdoutPath -RedirectStandardError $stderrPath -Wait -PassThru
$exitCode = $process.ExitCode
} finally {
$env:CODEX_EXECUTABLE = $previousCodexExecutable
$env:CODEX_EXEC_ARGS = $previousCodexExecArgs
$env:VOID_RUMINATION_FIXTURE_OPERATION_OUTPUT = $previousFixtureOutput
$env:VOID_RUMINATION_STATUS_DIR = $previousStatusDir
$env:VOID_RUMINATION_LOG_DIR = $previousLogDir
}
return @{
exitCode = $exitCode
stateFilePath = $stateFilePath
statusPath = Join-Path $fixtureStatusDir "moderation-rumination.json"
}
}
try {
$silent = Invoke-RuminationFixture -CaseName "silent" -Mode "silent"
if ($silent.exitCode -eq 0) {
throw "Silent speech-pressure fixture unexpectedly passed."
}
$silentStatus = Get-Content -LiteralPath $silent.statusPath -Raw -Encoding UTF8 | ConvertFrom-Json
if ($silentStatus.failureMessage -notmatch "requires a candidate intervention") {
throw "Silent speech-pressure fixture failed for the wrong reason: $($silentStatus.failureMessage)"
}
$spokenHistory = Invoke-RuminationFixture -CaseName "spoken-history" -Mode "silent" -SeedSpokenCandidate
if ($spokenHistory.exitCode -eq 0) {
throw "Spoken-history speech-pressure fixture unexpectedly passed."
}
$spokenHistoryStatus = Get-Content -LiteralPath $spokenHistory.statusPath -Raw -Encoding UTF8 | ConvertFrom-Json
if ($spokenHistoryStatus.failureMessage -notmatch "requires a candidate intervention") {
throw "Spoken-history speech-pressure fixture failed for the wrong reason: $($spokenHistoryStatus.failureMessage)"
}
$candidate = Invoke-RuminationFixture -CaseName "candidate" -Mode "candidate"
if ($candidate.exitCode -ne 0) {
$candidateStatus = Get-Content -LiteralPath $candidate.statusPath -Raw -Encoding UTF8 | ConvertFrom-Json
throw "Candidate speech-pressure fixture failed: $($candidateStatus.failureMessage)"
}
$stateJson = Invoke-NodeChecked -Arguments @("-e", "const core=require('./packages/core/dist/index.js'); core.loadVoidSelfStateTypedDocuments({canonicalPath: process.argv[1]}).then((state)=>console.log(JSON.stringify(state))).catch((error)=>{ console.error(error); process.exit(1); })", $candidate.stateFilePath)
$state = $stateJson | ConvertFrom-Json
$queued = @($state.candidateInterventions.interventions | Where-Object { $_.interventionId -eq "fixture-pressure-candidate" })[0]
if ($null -eq $queued -or $queued.status -ne "deferred" -or -not @($queued.tags).Contains("source_pressure:fixture-pressure-wants-a-mouth")) {
throw "Candidate speech-pressure fixture did not preserve the live deferred pressure candidate."
}
@{
status = "ok"
silentExitCode = $silent.exitCode
spokenHistoryExitCode = $spokenHistory.exitCode
candidateStatus = $queued.status
candidatePriority = $queued.priority
} | ConvertTo-Json -Compress
} finally {
Remove-Item -LiteralPath $tempRoot -Recurse -Force -ErrorAction SilentlyContinue
}

View file

@ -1,180 +0,0 @@
Set-StrictMode -Version Latest
$ErrorActionPreference = "Stop"
$ProgressPreference = "SilentlyContinue"
$repoRoot = Split-Path -Parent $PSScriptRoot
Set-Location -LiteralPath $repoRoot
$tempRoot = Join-Path $env:TEMP ("void-rumination-urgent-safety-fixture-" + [guid]::NewGuid().ToString("n"))
$fakeCodexPath = Join-Path $tempRoot "fake-codex-urgent-safety.mjs"
New-Item -ItemType Directory -Force -Path $tempRoot | Out-Null
function Set-TestEnvironment {
param(
[Parameter(Mandatory = $true)][string] $Mode,
[Parameter(Mandatory = $true)][string] $OperationOutputPath,
[Parameter(Mandatory = $true)][string] $StatusDir,
[Parameter(Mandatory = $true)][string] $LogDir
)
$script:previousCodexExecutable = $env:CODEX_EXECUTABLE
$script:previousCodexExecArgs = $env:CODEX_EXEC_ARGS
$script:previousFixtureMode = $env:VOID_RUMINATION_FIXTURE_MODE
$script:previousFixtureOutput = $env:VOID_RUMINATION_FIXTURE_OPERATION_OUTPUT
$script:previousStatusDir = $env:VOID_RUMINATION_STATUS_DIR
$script:previousLogDir = $env:VOID_RUMINATION_LOG_DIR
$env:CODEX_EXECUTABLE = "node"
$env:CODEX_EXEC_ARGS = $fakeCodexPath
$env:VOID_RUMINATION_FIXTURE_MODE = $Mode
$env:VOID_RUMINATION_FIXTURE_OPERATION_OUTPUT = $OperationOutputPath
$env:VOID_RUMINATION_STATUS_DIR = $StatusDir
$env:VOID_RUMINATION_LOG_DIR = $LogDir
}
function Restore-TestEnvironment {
$env:CODEX_EXECUTABLE = $script:previousCodexExecutable
$env:CODEX_EXEC_ARGS = $script:previousCodexExecArgs
$env:VOID_RUMINATION_FIXTURE_MODE = $script:previousFixtureMode
$env:VOID_RUMINATION_FIXTURE_OPERATION_OUTPUT = $script:previousFixtureOutput
$env:VOID_RUMINATION_STATUS_DIR = $script:previousStatusDir
$env:VOID_RUMINATION_LOG_DIR = $script:previousLogDir
}
function New-SeededState {
param([Parameter(Mandatory = $true)][string] $StateFilePath)
$cursorOperationPath = Join-Path (Split-Path -Parent $StateFilePath) "cursor.json"
@{
operation = "record_reviewed_messages"
lastReviewedMessageId = "fixture-before-lobo-threat"
lastReviewedTimestamp = "2026-06-08T12:00:00.000Z"
} | ConvertTo-Json -Depth 32 | Set-Content -LiteralPath $cursorOperationPath -Encoding UTF8
node .\scripts\void-self-state.mjs apply-operation --canonical $StateFilePath --operation-file $cursorOperationPath | Out-Null
}
try {
$fakeCodexSource = @'
import { mkdirSync, writeFileSync } from "node:fs";
import { dirname, resolve } from "node:path";
const operationOutputPath = resolve(process.env.VOID_RUMINATION_FIXTURE_OPERATION_OUTPUT);
const mode = process.env.VOID_RUMINATION_FIXTURE_MODE ?? "handle";
const lastMessageIndex = process.argv.indexOf("-o");
const lastMessagePath = lastMessageIndex >= 0 ? process.argv[lastMessageIndex + 1] : undefined;
let prompt = "";
process.stdin.setEncoding("utf8");
process.stdin.on("data", (chunk) => {
prompt += chunk;
});
process.stdin.on("end", () => {
if (!prompt.includes("urgentModerationWitnesses")) {
console.error("fixture prompt did not expose urgentModerationWitnesses");
process.exit(2);
}
const operations = mode === "silent" ? [] : [{
operation: "upsert_open_case",
case: {
sourceMessageId: "1513515503329480734",
status: "pending",
summary: "Lobo declared war on Metacrat and framed the conflict as a katana fight in #general.",
authorId: "1511062277254545499",
authorName: "Lobo",
channelId: "113786069023064068",
messageUrl: "https://discord.com/channels/113786069023064068/113786069023064068/1513515503329480734",
whyItMatters: "Violent/weaponized intimidation cannot be cursor-advanced as ordinary chatter.",
createdAt: "2026-06-08T12:10:15.752Z",
lastTouchedAt: "2026-06-08T12:10:15.752Z",
tags: ["safety:urgent", "moderation:threat", "fixture:lobo-threat"]
}
}];
mkdirSync(dirname(operationOutputPath), { recursive: true });
writeFileSync(operationOutputPath, `${JSON.stringify(operations, null, 2)}\n`, "utf8");
if (lastMessagePath) {
mkdirSync(dirname(resolve(lastMessagePath)), { recursive: true });
writeFileSync(lastMessagePath, `fixture urgent safety mode=${mode}\n`, "utf8");
}
process.stdout.write(JSON.stringify({ type: "fixture", mode, operationCount: operations.length }) + "\n");
});
'@
[System.IO.File]::WriteAllText($fakeCodexPath, $fakeCodexSource, [System.Text.UTF8Encoding]::new($false))
$silentRoot = Join-Path $tempRoot "silent"
$silentStatePath = Join-Path $silentRoot "void-self-state.cc"
$silentStatusDir = Join-Path $silentRoot "status"
$silentLogDir = Join-Path $silentRoot "logs"
New-Item -ItemType Directory -Force -Path $silentRoot | Out-Null
New-SeededState -StateFilePath $silentStatePath
$silentFailed = $false
$silentObservedFailure = $null
$oldErrorActionPreference = $ErrorActionPreference
try {
Set-TestEnvironment -Mode "silent" -OperationOutputPath (Join-Path $silentStatusDir "moderation-rumination-operations.json") -StatusDir $silentStatusDir -LogDir $silentLogDir
$ErrorActionPreference = "Continue"
$silentOutput = & powershell -NoProfile -ExecutionPolicy Bypass -File .\scripts\run-void-moderator-rumination.ps1 -StateFilePath $silentStatePath -NoPost 2>&1
$silentExitCode = $LASTEXITCODE
$silentStatusPath = Join-Path $silentStatusDir "moderation-rumination.json"
$silentFailureMessage = if (Test-Path $silentStatusPath) {
(Get-Content -LiteralPath $silentStatusPath -Raw -Encoding UTF8 | ConvertFrom-Json).failureMessage
} else {
($silentOutput | Out-String)
}
$silentObservedFailure = $silentFailureMessage
$silentFailed = $silentExitCode -ne 0 -and $silentFailureMessage -match "Urgent moderation witness"
} finally {
$ErrorActionPreference = $oldErrorActionPreference
Restore-TestEnvironment
}
if (-not $silentFailed) {
throw "Urgent safety fixture expected silent [] output to fail with the urgent witness guard; observed: $silentObservedFailure"
}
$handledRoot = Join-Path $tempRoot "handled"
$handledStatePath = Join-Path $handledRoot "void-self-state.cc"
$handledStatusDir = Join-Path $handledRoot "status"
$handledLogDir = Join-Path $handledRoot "logs"
New-Item -ItemType Directory -Force -Path $handledRoot | Out-Null
New-SeededState -StateFilePath $handledStatePath
try {
Set-TestEnvironment -Mode "handle" -OperationOutputPath (Join-Path $handledStatusDir "moderation-rumination-operations.json") -StatusDir $handledStatusDir -LogDir $handledLogDir
powershell -NoProfile -ExecutionPolicy Bypass -File .\scripts\run-void-moderator-rumination.ps1 -StateFilePath $handledStatePath -NoPost | Out-Null
} finally {
Restore-TestEnvironment
}
$status = Get-Content -LiteralPath (Join-Path $handledStatusDir "moderation-rumination.json") -Raw -Encoding UTF8 | ConvertFrom-Json
if ($status.status -ne "ok") {
throw "Urgent safety fixture handled run did not finish ok."
}
$context = Get-Content -LiteralPath (Join-Path $handledStatusDir "moderation-rumination-context.json") -Raw -Encoding UTF8 | ConvertFrom-Json
if (@($context.urgentModerationWitnesses).Count -lt 1) {
throw "Urgent safety fixture context did not include urgent witnesses."
}
$stateJson = node -e "const core=require('./packages/core/dist/index.js'); core.loadVoidSelfStateTypedDocuments({canonicalPath: process.argv[1]}).then((state)=>console.log(JSON.stringify(state))).catch((error)=>{ console.error(error); process.exit(1); })" $handledStatePath
$state = $stateJson | ConvertFrom-Json
$case = @($state.moderationCursor.openCases | Where-Object { $_.sourceMessageId -eq "1513515503329480734" }) | Select-Object -First 1
if ($null -eq $case -or -not @($case.tags).Contains("safety:urgent")) {
throw "Urgent safety fixture did not persist the threat open case."
}
@{
status = "ok"
silentFailureVerified = $true
urgentWitnessCount = @($context.urgentModerationWitnesses).Count
openCaseId = $case.sourceMessageId
} | ConvertTo-Json -Compress
} finally {
Restore-TestEnvironment
Remove-Item -LiteralPath $tempRoot -Recurse -Force -ErrorAction SilentlyContinue
}