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
13 changes: 13 additions & 0 deletions .claude/skills/t27os/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,19 @@ dashboard and back). The window only calls the decisions of `bench.t27`, `kanban
duplicate-name script before importing a new spec into `glass_window`. The fast `t27b test` does not type-check the
non-test functions unless an error forces the full checker (add an unknown name to a scratch copy).

## Updates on the fly (owner, 2026-10-20; rules and tests: `specs/t27os/release.t27`, host: `glass_window.t27` update_tick)

Every machine updates itself online. At launch and every 10 minutes the app fetches the manifest of the release named
`t27os-latest` (assets replaced on every publish; releases are tagged `t27os-v<semver>-b<build>`, never `v*`). A newer
build is downloaded to `~/.t27os/updates/<build>/`, checked against the manifest's sha256 rows, unzipped, signed ad hoc
and verified, and swapped in only when no pane is busy (quiet 60 s, or the **UPDATE NOW** line above the sidebar foot).
The previous bundle stays in `~/.t27os/updates/previous`; a start that dies within 60 s is rolled back by the next one,
which refuses that build. Each release also ships arm64 `t27b`, `t27c`, `tri` built from the same commit; they go to
`~/.t27os/bin` (first on every pane's PATH, `.prev` kept) only when their `--version` names the manifest's COMMIT.
The pane server runs under launchd (`ai.t27.os.pty`, never a child of the app or a shell) and is restarted only when its
own digest changed. Publish: `tri t27os publish --yes` (owner's word); `tri t27os release --plan` prints the steps.
A copy that is not a built bundle (build 0), or runs from a checkout's `target/` folder, never updates itself.

## The image (owner, 2026-10-20)

We sit in a spaceship; T27 OS is its **instrument panel** for working on the project.
Expand Down
14 changes: 7 additions & 7 deletions .trinity/seals/t27os_T27osPlistMain.json
Original file line number Diff line number Diff line change
@@ -1,30 +1,30 @@
{
"built_by": "t27c-bootstrap@0.5.2+24a3abcad",
"built_by": "t27c-bootstrap@0.5.2+72ddaf7ac",
"closure": [
{
"spec": "specs/t27os/install.t27",
"spec_hash": "sha256:3f6012f40457db8c325f856b28563dad4a02e08455fd12ecb63794c7a51dc318"
},
{
"spec": "specs/t27os/pty_sys.t27",
"spec_hash": "sha256:de47b090b70077f3f6eb52a582c3e6383186f2bab5e27a61e3d276c66bcedef4"
"spec_hash": "sha256:3ac9847c20720e1bce3411ef0284fa268d83e6f2c29375cf7fed088d987a5697"
},
{
"spec": "specs/t27os/release.t27",
"spec_hash": "sha256:5ee4dc49a78a23c65e03a90051c40545805e1d99a92b41fa08dde8fee24bcce7"
"spec_hash": "sha256:90e4fdcfa27b20354de9e9f3ef8a527eaa817c0ca4779565d12228ab58a8e587"
}
],
"config": "gen=c,rust,verilog,zig;tests=zig",
"gen_hash_c": "sha256:445ec28fad7fc375b00699d02d3a06957e2af695a3a25ea72252e98ad096bfe1",
"gen_hash_c": "sha256:22c150be5b359b4f32171a158a3291a892744816fdc2d144ca86335def6940b1",
"gen_hash_rust": "sha256:f05b5c44e7b68b9037eeda9d40ef9735cba6348414b2b0685d9c688b0eba989a",
"gen_hash_verilog": "sha256:1bfa9c08ace2985e9ad73b04605f74ec3009156d079422f064dee9d109570926",
"gen_hash_zig": "sha256:cbd4b513c7a0554abcf5ddc29eeb761cb952b13da853b282b1b43eb4cc9a76d2",
"gen_hash_zig": "sha256:7f61684a719d588f97419bac4bd960a86a70a1787d5e3997d0776f0fbe355420",
"module": "T27osPlistMain",
"ring": 12,
"seal_schema": 2,
"sealed_at": "2026-10-20T10:17:56Z",
"sealed_at": "2026-10-20T16:26:33Z",
"sealed_by": "t27c-bootstrap@0.5.2",
"spec_hash": "sha256:5257c41c568bb80177c6db8293da719e27627f8b58a68a4f7eda9380d12a05b2",
"spec_hash": "sha256:832430ff44919f2b599b7960f2c5e25f770255c72fefa6247705d0652149e431",
"spec_path": "specs/t27os/plist_main.t27",
"tests": {
"blocked": "does not compile: spec.zig:136:5: error: expected 2 arguments, found 1"
Expand Down
18 changes: 9 additions & 9 deletions .trinity/seals/t27os_T27osPtyLogic.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"built_by": "t27c-bootstrap@0.5.2+24a3abcad",
"built_by": "t27c-bootstrap@0.5.2+72ddaf7ac",
"closure": [
{
"spec": "specs/t27os/agents.t27",
Expand Down Expand Up @@ -27,23 +27,23 @@
}
],
"config": "gen=c,rust,verilog,zig;tests=zig",
"gen_hash_c": "sha256:50540d12ad38aca7c26bfbb2949afcef24efe46b6ee84f4730413464bdd95d8a",
"gen_hash_rust": "sha256:06bfd8cc1b54ae0abdc31c304afe4411e92860a9de08cf85252b4b51491b6913",
"gen_hash_verilog": "sha256:04b6cac172b4a27a5dca420d2d4a45ba4e09f0b3c8d0c06ac87dcf07ce4e1b1f",
"gen_hash_zig": "sha256:b53b7a9436691b03637121114b136451b2a77265067be825a3e7aae77dbeadc6",
"gen_hash_c": "sha256:db15cda07d74f76bfd3f66a0c28696f4d6bcc3a7a272af26871d93da3a3b0335",
"gen_hash_rust": "sha256:e877769438a825b3c691c361be574a832fbc4b9ae4117bacd16193c3e0b95488",
"gen_hash_verilog": "sha256:7777695c6de77e842e7e32037bb2537ddad75c1d66c2113f72eee56f4e29569b",
"gen_hash_zig": "sha256:d48931415ec290196ef0aec5732594b63f1b5ee047c77de807b1050ebd030bd4",
"module": "T27osPtyLogic",
"ring": 12,
"seal_schema": 2,
"sealed_at": "2026-10-20T13:16:02Z",
"sealed_at": "2026-10-20T16:20:00Z",
"sealed_by": "t27c-bootstrap@0.5.2",
"spec_hash": "sha256:d5f43766bbba3a606ad31a211533bd2a89cf8fbd18d9457d788adea9fca05cd8",
"spec_hash": "sha256:5a99eca9bff18d358ab6f705ad4b4e2e50d47e98906c6d09e069fd81d6f5be65",
"spec_path": "specs/t27os/pty_logic.t27",
"tests": {
"failed": 0,
"failing": [],
"forced": false,
"passed": 53,
"total": 53,
"passed": 54,
"total": 54,
"vacuous": 0
},
"toolchain": {
Expand Down
18 changes: 9 additions & 9 deletions .trinity/seals/t27os_T27osRelease.json
Original file line number Diff line number Diff line change
@@ -1,29 +1,29 @@
{
"built_by": "t27c-bootstrap@0.5.2+24a3abcad",
"built_by": "t27c-bootstrap@0.5.2+72ddaf7ac",
"closure": [
{
"spec": "specs/claw/text.t27",
"spec_hash": "sha256:968755ec1917f766eb2cdd0ab4c0c48aef028a0e7d69e191911695e925b286ad"
}
],
"config": "gen=c,rust,verilog,zig;tests=zig",
"gen_hash_c": "sha256:19600e42829e3c70e1546fe00fba6718102a7d833fd831fdbccb68a67167e528",
"gen_hash_rust": "sha256:2b0227b6b45e3d9932295bee744bd2633f072ce263d47360486aa3ec0689cbe9",
"gen_hash_verilog": "sha256:1674b0bc8c28ae7610d0ae9b584f941d004c066f283383302b2158e3b6abce1d",
"gen_hash_zig": "sha256:b8677674704a0caacfdb7bbeafa44282c8244064906db85020303f78e53ed343",
"gen_hash_c": "sha256:0dd9cc394bb59945f2a983299e2b7a761b0ef587e467574021edaebd7b2d45a4",
"gen_hash_rust": "sha256:f4c0cfff38dc232f79a49d1eaa5f243dcd999934604c1cf75e5b13a40d504c05",
"gen_hash_verilog": "sha256:206a1e00867925f9073cea465d1f69658c4330948120ba0a58c8033d5fa0ed9b",
"gen_hash_zig": "sha256:f1aa877dd8ad842c762dd191030a8ef6054b26ede3466bed7e6d55ec18e9028c",
"module": "T27osRelease",
"ring": 12,
"seal_schema": 2,
"sealed_at": "2026-10-20T10:17:53Z",
"sealed_at": "2026-10-20T16:26:32Z",
"sealed_by": "t27c-bootstrap@0.5.2",
"spec_hash": "sha256:5ee4dc49a78a23c65e03a90051c40545805e1d99a92b41fa08dde8fee24bcce7",
"spec_hash": "sha256:90e4fdcfa27b20354de9e9f3ef8a527eaa817c0ca4779565d12228ab58a8e587",
"spec_path": "specs/t27os/release.t27",
"tests": {
"failed": 0,
"failing": [],
"forced": false,
"passed": 21,
"total": 21,
"passed": 36,
"total": 36,
"vacuous": 0
},
"toolchain": {
Expand Down
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ install:
@test "$(EARN)" != on || { echo "EARN=on: no lab node ships in this checkout yet; nothing was installed" >&2; exit 2; }
./scripts/tri disk
cargo build --release -p t27c -p tri $(if $(T27B),-p t27b)
@test -z "$(PIN)" || test "$$(target/release/t27c --version)" = "t27c $(PIN)" || { echo "version pin $(PIN) not met: $$(target/release/t27c --version)" >&2; exit 2; }
@test -z "$(PIN)" || test "$$(target/release/t27c --version | head -1)" = "t27c $(PIN)" || { echo "version pin $(PIN) not met: $$(target/release/t27c --version | head -1)" >&2; exit 2; }
@set -e; for p in $(PAIRS); do s=$${p%%:*}; d=$(PREFIX)/$${p#*:}; mkdir -p "$$(dirname "$$d")"; m=755; case "$$s" in specs/*|.trinity/*) m=644;; esac; install -C -m $$m "$$s" "$$d"; done
@set -e; mkdir -p $(PREFIX)/share/t27; m=$$({ cat $(LIST) 2>/dev/null || :; printf '%s\n' $(PAIRS) | sed 's/^[^:]*://'; echo share/t27/install.list; } | sort -u); [ "$$m" = "$$(cat $(LIST) 2>/dev/null)" ] || printf '%s\n' "$$m" > $(LIST)
$(if $(filter on,$(CLAW)),@cd $(PREFIX)/share/t27/claw && $(PREFIX)/bin/t27c seal --verify specs/claw/service.t27)
Expand Down
3 changes: 1 addition & 2 deletions bootstrap/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -192,8 +192,6 @@ use std::path::{Path, PathBuf};

#[derive(Parser)]
#[command(name = "t27c")]
// `t27c version` existed; `--version` and `-V` did not, so the flag every
// other CLI answers returned "unexpected argument". One attribute.
#[command(version)]
#[command(about = "T27 Bootstrap Compiler for Trinity S³AI Framework", long_about = None)]
struct Cli {
Expand Down Expand Up @@ -11955,6 +11953,7 @@ fn run_gen_behavior_sva_v2(

#[cfg(not(feature = "server"))]
fn main() -> anyhow::Result<()> {
if std::env::args().nth(1).as_deref() == Some("--version") { println!("t27c {}\nbuild {} commit {}", env!("CARGO_PKG_VERSION"), option_env!("T27_BUILD").unwrap_or("0"), option_env!("T27_COMMIT").unwrap_or("unknown")); return Ok(()) }
let cli = Cli::parse();

match cli.command {
Expand Down
5 changes: 2 additions & 3 deletions cli/t27b/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,7 @@ use t27b::eval::{Interp, Stop};
use t27b::ir::{OverflowMode, Program, Ty};
use t27b::jit::Jit;
use t27b::timing::Phases;
#[path = "../../../gen/rust/tri/t27b/check_budget.rs"]
#[allow(dead_code, unused_parens)]
mod check_budget; // --check fuel policy, t27c gen-rust of specs/tri/t27b/check_budget.t27 (#6664)
#[path = "../../../gen/rust/tri/t27b/check_budget.rs"] #[allow(dead_code, unused_parens)] mod check_budget; // --check fuel policy, t27c gen-rust of specs/tri/t27b/check_budget.t27 (#6664)
#[path = "../../../gen/rust/tri/t27b/watch_build.rs"] #[allow(dead_code, unused_parens)] mod watch_build; // `t27b watch`: when to build, the temp path, when --then runs (#10859)
use t27b::blockers::{self, Reference, Verdicts};
use t27b::{a64, front, lower, macho};
Expand Down Expand Up @@ -197,6 +195,7 @@ fn main() -> ExitCode {
};
cmd_corpus(Path::new(&dir), &o)
}
"--version" | "-V" => { outln!("t27b {}\nbuild {} commit {}", env!("CARGO_PKG_VERSION"), option_env!("T27_BUILD").unwrap_or("0"), option_env!("T27_COMMIT").unwrap_or("unknown")); ExitCode::SUCCESS }
"help" | "--help" | "-h" => {
outln!("{}", USAGE);
ExitCode::SUCCESS
Expand Down
22 changes: 12 additions & 10 deletions cli/tri/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -459,8 +459,8 @@ enum Commands {
Land { branch: Option<String>, #[arg(long, default_value_t = 0)] issue: u64, #[arg(long)] plan: bool, #[arg(long)] check: bool },
/// The golden chain's front door: `land` verifies each queued claude/evolve-* branch locally and lands the ready ones on refs/golden/head by compare-and-swap (--plan writes nothing), `push` sends the unpushed links to GitHub as one `tri land` pull request when the window is due (--queued N overrides the Actions queue count, --issue N is the Closes #N), `status` prints head, queue and the next push time (rules: specs/queen/golden_chain.t27 section 6, hosted by specs/tri/land/golden_land.t27, #11275).
Golden { action: String, #[arg(long)] plan: bool, #[arg(long)] queued: Option<u64>, #[arg(long, default_value_t = 0)] issue: u64 },
/// T27 OS release front door: `release --plan` prints the numbered steps (build, zip, sha256, manifest, notes, `gh release create`) and runs none; `manifest --build N --sha H` prints the release manifest, a t27 module the app reads; anything that would publish is refused (rules: specs/t27os/release.t27, #11315).
T27os { action: String, #[arg(long)] plan: bool, #[arg(long, default_value_t = 0)] build: u32, #[arg(long, default_value = "")] sha: String },
/// T27 OS release front door: `release --plan` prints the numbered steps; `manifest --build N --sums FILE` prints the release manifest, a t27 module the app reads; `publish --yes` builds app and toolchain from one clean commit and creates the t27os-v<version>-b<build> release and the t27os-latest pointer; without --yes it is refused (rules: specs/t27os/release.t27, #11315, #11403).
T27os { action: String, #[arg(long)] plan: bool, #[arg(long)] yes: bool, #[arg(long, default_value_t = 0)] build: u32, #[arg(long, default_value = "")] sums: String },
/// Coverage of a set of specs by five facts each, one row per spec and a total: the tests ran and none failed, no vacuous pass, a test named for a refusal or a planted fault (negative control), the seal verifies, and the header names an issue. PATTERN is a path or a glob (`specs/lab/*.t27`); the last line is `gaps G coverage N/D`, never rounded. Exit 0 once printed, 1 on a gap with --strict, 2 when no spec matched; --t27c names the t27c program (default target/release/t27c, then t27c on PATH) (rules: specs/tri/coverage/coverage.t27, #11061).
Coverage { patterns: Vec<String>, #[arg(long)] strict: bool, #[arg(long)] t27c: Option<String> },
/// Add one lesson to the Traps section of a skill unless the section already says it; `tri learn add --help` has the refusals (rules: specs/tri/loop/lesson.t27, #11060).
Expand Down Expand Up @@ -1244,6 +1244,7 @@ fn cmd_health(root: &Path, target: Option<&str>) -> Result<()> {
}

fn main() -> Result<()> {
if std::env::args().nth(1).as_deref() == Some("--version") { let mut b = [0u8; 256]; let n = t27rel::version_text(&mut b, 256, "tri", env!("CARGO_PKG_VERSION"), option_env!("T27_BUILD").and_then(|s| s.parse().ok()).unwrap_or(0), option_env!("T27_COMMIT").unwrap_or("unknown")); print!("{}", String::from_utf8_lossy(&b[..n])); return Ok(()) }
let cli = Cli::parse();

match &cli.command {
Expand Down Expand Up @@ -1385,7 +1386,7 @@ fn main() -> Result<()> {
Commands::T27o { file, name, oracle, check, t27c, emit_cell } => std::process::exit(cmd_t27o(file, name.as_deref(), *oracle, *check, t27c.as_deref(), *emit_cell)? as i32),
Commands::T27oSweep { paths, repo, max_bytes, cache, top } => std::process::exit(cmd_t27o_sweep(paths, repo, *max_bytes, cache.as_deref(), *top)? as i32),
Commands::Golden { action, plan, queued, issue } => std::process::exit(cmd_golden(action, *plan, *queued, *issue)? as i32),
Commands::T27os { action, plan, build, sha } => std::process::exit(cmd_t27os(action, *plan, *build, sha)),
Commands::T27os { action, plan, yes, build, sums } => std::process::exit(cmd_t27os(action, *plan, *yes, *build, sums)),
Commands::Land { branch, issue, plan, check } => std::process::exit(cmd_land(branch.as_deref(), *issue, *plan, *check, false)? as i32),
Commands::Coverage { patterns, strict, t27c } => std::process::exit(seals::coverage_run(patterns, *strict, t27c.as_deref())?),
Commands::Learn { action } => loopclaim::learn_run(action)?,
Expand Down Expand Up @@ -1576,13 +1577,14 @@ fn cmd_golden(action: &str, plan: bool, queued: Option<u64>, issue: u64) -> Resu
Ok(g::exit_code(code))
}

/// `tri t27os release --plan` | `manifest` (#11315): the text is specs/t27os/release.t27; this prints it and publishes nothing.
fn cmd_t27os(action: &str, plan: bool, build: u32, sha: &str) -> i32 {
let (mut buf, v) = (vec![0u8; 4096], t27rel::current_version());
/// `tri t27os release --plan` | `manifest` | `publish --yes` (#11315, #11403): the texts are specs/t27os/release.t27.
fn cmd_t27os(action: &str, plan: bool, yes: bool, build: u32, sums: &str) -> i32 {
let (mut buf, v, s) = (vec![0u8; 8192], t27rel::current_version(), std::fs::read(sums).unwrap_or_default());
let n = match action {
"release" if plan && !t27rel::publish_allowed(plan, false) => t27rel::plan_text(&mut buf, 4096, v),
"manifest" if build > 0 && t27rel::sha_ok(sha.as_bytes(), sha.len()) => t27rel::manifest_text(&mut buf, 4096, v, build, sha.as_bytes(), sha.len()),
_ => { eprintln!("{}", if action == "manifest" { "tri t27os manifest: --build N and --sha <64 lowercase hex digits> are required" } else { t27rel::REFUSAL }); return 2 }
"release" if plan => t27rel::plan_text(&mut buf, 8192, v),
"manifest" if build > 0 => t27rel::manifest_from_sums(&mut buf, 8192, v, build, &s, s.len()),
"publish" if t27rel::publish_allowed(plan, yes) => { let n = t27rel::publish_text(&mut buf, 8192, v); return Command::new("sh").arg("-c").arg(String::from_utf8_lossy(&buf[..n.min(8192)]).as_ref()).status().map_or(2, |x| x.code().unwrap_or(2)) }
_ => { eprintln!("{}", if action == "manifest" { "tri t27os manifest: --build N and --sums <complete sums file> are required" } else { t27rel::REFUSAL }); return 2 }
};
print!("{}", String::from_utf8_lossy(&buf[..n.min(4096)])); (n > 4096) as i32
print!("{}", String::from_utf8_lossy(&buf[..n.min(8192)])); (n == 0 || n > 8192) as i32
}
2 changes: 1 addition & 1 deletion cli/tri/src/seals.rs
Original file line number Diff line number Diff line change
Expand Up @@ -705,7 +705,7 @@ pub fn run(cmd: &SealsCmd) -> Result<()> {
sync_twins(&root, &dir, false)?;
return Ok(());
}
SealsCmd::Twins { all } => all,
SealsCmd::Twins { all } => all, SealsCmd::Changed | SealsCmd::MergeDriver { .. } => return Ok(()),
};
let by = collect(&dir)?;

Expand Down
Loading
Loading