Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 28 additions & 0 deletions .trinity/seals/t27os_T27osSwarmPulse.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
{
"built_by": "t27c-bootstrap@0.5.2+24a3abcad",
"closure": [],
"config": "gen=c,rust,verilog,zig;tests=zig",
"gen_hash_c": "sha256:1c8c7a0ab694e36ce7b45f4f5d39507a7c0e05d3ecb3173ee22c4a5f306223f1",
"gen_hash_rust": "sha256:db89d95d7cac5981f484d96a3e22c5ec8bf7cb6c48f71777887b40a84a32da1b",
"gen_hash_verilog": "sha256:e67c25f6f31f6a7f5de455246134f0b909fedcf04c1a81afc59e96e7bdb42ce3",
"gen_hash_zig": "sha256:5a341440e343e700df7522a34be89cdd06b4963c5a83c238f114a418442f7cd9",
"module": "T27osSwarmPulse",
"ring": 12,
"seal_schema": 2,
"sealed_at": "2026-10-20T11:54:31Z",
"sealed_by": "t27c-bootstrap@0.5.2",
"spec_hash": "sha256:57e4bf04a42c6a85e0326a28d377b37837f2c9dac8cd988c792655aae12044ad",
"spec_path": "specs/t27os/swarm_pulse.t27",
"tests": {
"failed": 0,
"failing": [],
"forced": false,
"passed": 6,
"total": 6,
"vacuous": 0
},
"toolchain": {
"test_runner": "sha256:8512b80da533b79289110fca4a65f3336abd7a059ca4b72ea595d5e33ff8ad10",
"zig": "0.16.0"
}
}
112 changes: 112 additions & 0 deletions specs/t27os/swarm_pulse.t27
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
// SPDX-License-Identifier: Apache-2.0
; specs/t27os/swarm_pulse.t27 -- the hourly watch of the swarm: from the numbers the pulse collects (bee jobs running
; and queued, swarm issues waiting, agent lanes on this machine, free-tier keys, free disk) it decides ONE action.
; Owner, 2026-10-20: "switch on a cron that watches that everyone works at maximum efficiency", "show bee load and
; token stock online so there is no idle time", "all logic is written in .t27". The collector that reads the numbers
; is plumbing (gh, security without -w, df); every threshold and every decision is here, tested.
; Refs epic #11275; issue #11331 family (swarm work under the T27 OS epic). ASCII only (L3), English only (LANG-EN).
; --
; THE ORDER of the rules is the order of harm: no disk stops every build (clean first); no keys stops every lane
; (request keys); idle capacity with work waiting wastes time (start one free-tier lane); otherwise nothing.
; A tick takes at most ONE action, so a watch never floods the machine or the owner.
; phi^2 + 1/phi^2 = 3 | TRINITY
module T27osSwarmPulse;

/// Below this many free gigabytes no cargo, t27b app or nextpnr build starts (peer rule, 2026-10-20).
pub const MIN_DISK_GB : u32 = 8;
/// Fewer usable z.ai free keys than this, or no OpenRouter key, is a key shortage.
pub const MIN_ZAI_KEYS : u32 = 3;
pub const MIN_OPENROUTER_KEYS : u32 = 1;
/// The minute of the hour the watch fires (off the :00 and :30 marks).
pub const TICK_MINUTE : u32 = 17;

pub const ST_BUSY : u8 = 0;
pub const ST_HUNGRY : u8 = 1;
pub const ST_IDLE : u8 = 2;

pub const ACT_NONE : u8 = 0;
pub const ACT_CLEAN_DISK : u8 = 1;
pub const ACT_REQUEST_KEYS : u8 = 2;
pub const ACT_START_LANE : u8 = 3;

/// IDLE: no bee job runs and none waits. HUNGRY: nothing queued while swarm issues wait. BUSY otherwise.
pub fn state_of(running: u32, queued: u32, waiting: u32) -> u8 {
if (running == 0 and queued == 0) { return ST_IDLE; }
if (queued == 0 and waiting > 0) { return ST_HUNGRY; }
return ST_BUSY;
}

pub fn builds_allowed(disk_gb: u32) -> bool {
return disk_gb >= MIN_DISK_GB;
}

pub fn keys_short(zai: u32, openrouter: u32) -> bool {
return zai < MIN_ZAI_KEYS or openrouter < MIN_OPENROUTER_KEYS;
}

/// One more free-tier lane is worth starting: nothing queued, work waiting, and the machine below its lane cap
/// (the cap is kernel.t27 agent_cap for this machine, passed in).
pub fn lane_wanted(queued: u32, waiting: u32, lanes: u32, cap: u32) -> bool {
return queued == 0 and waiting > 0 and lanes < cap;
}

/// The one action of a tick, in the order of harm.
pub fn action_of(running: u32, queued: u32, waiting: u32, lanes: u32, cap: u32, zai: u32, openrouter: u32, disk_gb: u32) -> u8 {
if (!builds_allowed(disk_gb)) { return ACT_CLEAN_DISK; }
if (keys_short(zai, openrouter)) { return ACT_REQUEST_KEYS; }
if (lane_wanted(queued, waiting, lanes, cap)) { return ACT_START_LANE; }
return ACT_NONE;
}

pub fn action_name(a: u8) -> string {
if (a == ACT_CLEAN_DISK) { return "clean disk, no builds"; }
if (a == ACT_REQUEST_KEYS) { return "request keys from the owner"; }
if (a == ACT_START_LANE) { return "start one free-tier lane"; }
return "none";
}

pub fn state_name(s: u8) -> string {
if (s == ST_IDLE) { return "IDLE"; }
if (s == ST_HUNGRY) { return "HUNGRY"; }
return "BUSY";
}

// --- tests ---------------------------------------------------------------------------------------------------

test the_first_real_pulse_reads_hungry_and_wants_a_lane {
// 2026-10-20 19:05Z: 3 jobs running, 0 queued, 16 swarm issues filed, 1 lane of cap 3
assert state_of(3, 0, 16) == ST_HUNGRY;
assert action_of(3, 0, 16, 1, 3, 7, 1, 8) == ACT_START_LANE;
}

test idle_needs_both_zero {
assert state_of(0, 0, 0) == ST_IDLE;
assert state_of(0, 1, 5) == ST_BUSY;
assert state_of(2, 4, 5) == ST_BUSY;
}

test disk_comes_before_keys_and_lanes {
assert action_of(0, 0, 9, 0, 3, 0, 0, 6) == ACT_CLEAN_DISK;
assert builds_allowed(8) and !builds_allowed(7);
}

test keys_come_before_lanes {
assert action_of(0, 0, 9, 0, 3, 2, 1, 20) == ACT_REQUEST_KEYS;
assert action_of(0, 0, 9, 0, 3, 7, 0, 20) == ACT_REQUEST_KEYS;
assert !keys_short(3, 1);
}

test no_lane_over_the_cap_or_without_work {
assert action_of(0, 0, 9, 3, 3, 7, 1, 20) == ACT_NONE;
assert action_of(0, 0, 0, 0, 3, 7, 1, 20) == ACT_NONE;
assert action_of(0, 2, 9, 0, 3, 7, 1, 20) == ACT_NONE;
}

test names_are_stable {
assert action_name(ACT_START_LANE) == "start one free-tier lane";
assert state_name(ST_HUNGRY) == "HUNGRY";
}

invariant a_tick_takes_at_most_one_action {
assert action_of(0, 0, 9, 0, 3, 0, 0, 0) == ACT_CLEAN_DISK;
}
Loading