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
27 changes: 18 additions & 9 deletions .trinity/seals/t27o_T27oLedger.json
Original file line number Diff line number Diff line change
@@ -1,24 +1,33 @@
{
"built_by": "t27c-bootstrap@0.5.2+9b556b7c3",
"closure": [],
"closure": [
{
"spec": "specs/tri/lab/receipt.t27",
"spec_hash": "sha256:00d9eec8d7be84dde596c9990b3a5574de24aff9f7a94579fc620eb585712441"
},
{
"spec": "specs/tri/reseal/seal.t27",
"spec_hash": "sha256:58eed39e2ed5b40cca6c35c5f951e867a7f92cb260972ee0305278f1e0028a47"
}
],
"config": "gen=c,rust,verilog,zig;tests=zig",
"gen_hash_c": "sha256:7718109194bbe93a643a14dc387c9a9ea965f5762a1a61273fb9e25f5a598488",
"gen_hash_rust": "sha256:c1b340dbe2e18469610447bce3edc48acde9c30b06544ad97038b5ddeb436793",
"gen_hash_verilog": "sha256:4463b9a8fcef3622b4e17271e74d188615cde707c432fa11efbcacfcce5612ae",
"gen_hash_zig": "sha256:edb095d112d0f61f6ab296e112409cab0fc978dc21acd18eeca6e7a3fc70d00f",
"gen_hash_c": "sha256:70b876438caf032fd5539af93b210cec8f661ab519bb418ffdfb33d7c9f55eac",
"gen_hash_rust": "sha256:81513af17b39ada3c99c5b4340270456c67cfb1ff592ff82c35e032541210e0a",
"gen_hash_verilog": "sha256:42e96be374322dd1a6a2dfd10d9e598eb6c670d338f6c80f6c3bc8403ce84b87",
"gen_hash_zig": "sha256:27cc3b986f364b51e0a64ec4ceb5334b57bb9eca2a1d698ca08f6c4a8ffb10a8",
"module": "T27oLedger",
"ring": 12,
"seal_schema": 2,
"sealed_at": "2026-10-18T16:37:38Z",
"sealed_at": "2026-10-18T18:07:43Z",
"sealed_by": "t27c-bootstrap@0.5.2",
"spec_hash": "sha256:03a101483be4dbd1be9f5e1dde9681ab01c513256138a0de37241b58db6b32d4",
"spec_hash": "sha256:c8ced20f9d10b20c8cfe366b991b34d2053775d9ea26fb656aeacf70d8004574",
"spec_path": "specs/tools/t27o/ledger.t27",
"tests": {
"failed": 0,
"failing": [],
"forced": false,
"passed": 12,
"total": 12,
"passed": 23,
"total": 23,
"vacuous": 0
},
"toolchain": {
Expand Down
14 changes: 0 additions & 14 deletions cli/dlc10/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1813,20 +1813,6 @@ fn extract_rx(resp: &[u8], total_bits: usize, rx_start_bits: usize, rx_len_bits:
out
}

/// Default JTAG-bit latency between TDI presentation and the corresponding
/// TDO bit for the Migen JTAG2SPI bridge. The Verilog has a 2-stage MISO
/// flop (`negedge`/`miso_capture` then `tdo`) plus the JTAG host's own
/// 1-bit Capture-DR delay — so a starting guess of 3 is reasonable. Can
/// be overridden by `T27_DLC10_MIGEN_LATENCY` for empirical tuning.
const MIGEN_TDO_LATENCY_BITS_DEFAULT: usize = 3;

fn migen_latency() -> usize {
std::env::var("T27_DLC10_MIGEN_LATENCY")
.ok()
.and_then(|s| s.parse().ok())
.unwrap_or(MIGEN_TDO_LATENCY_BITS_DEFAULT)
}

/// Index into the DLC10 16-bit-LE packed response by absolute Shift-DR
/// bit position (LSB-first within each 16-bit word).
fn bit_at(resp: &[u8], bit_idx: usize) -> bool {
Expand Down
14 changes: 0 additions & 14 deletions cli/tri/src/depin/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,6 @@ pub struct EpochChallengeResponse {
pub struct MiningEpoch {
pub epoch_id: u64,
pub phi_seed: [u8; 16],
pub start_ts: u64,
pub block_reward: u64,
}

Expand All @@ -51,22 +50,9 @@ impl MiningEpoch {
Self {
epoch_id: 0,
phi_seed: [0u8; 16],
start_ts: 0,
block_reward: 50_000_000,
}
}

pub fn next(&self) -> Self {
let mut seed = [0u8; 16];
let hash = sha2_hash(&[b"EPOCH_SEED", &self.epoch_id.to_le_bytes(), &self.phi_seed]);
seed.copy_from_slice(&hash[..16]);
Self {
epoch_id: self.epoch_id + 1,
phi_seed: seed,
start_ts: 0,
block_reward: self.block_reward,
}
}
}

pub fn sha2_hash(inputs: &[&[u8]]) -> [u8; 32] {
Expand Down
14 changes: 0 additions & 14 deletions cli/tri/src/gates.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5775,20 +5775,6 @@ fn preview(base: &str) -> Result<()> {
Ok(())
}

// Its only caller was the `check-now-freshness` row of `preview`, removed in #5935.
#[allow(dead_code)]
fn rev(root: &std::path::Path, r: &str) -> Result<String> {
let out = std::process::Command::new("git")
.args(["rev-parse", r])
.current_dir(root)
.output()
.context("failed to invoke git rev-parse")?;
if !out.status.success() {
anyhow::bail!("git rev-parse {r} failed -- the revision is wrong, not the tree");
}
Ok(String::from_utf8_lossy(&out.stdout).trim().to_string())
}

/// The pull request's title and body, if this branch has one open.
fn pr_text(root: &std::path::Path) -> Option<String> {
let out = std::process::Command::new("gh")
Expand Down
34 changes: 34 additions & 0 deletions cli/tri/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -437,6 +437,8 @@ enum Commands {
/// The t27c binary; default target/release/t27c, then t27c on PATH.
#[arg(long)] t27c: Option<String>,
},
/// t27o over a tree (#10543): every tracked .rs file converted in-process; a file's row is reused while its key holds (its SHA-256 and the seals of rust_convert.t27 and rust_std.t27); counts, coverage and the ranked first-refusal kinds (rules: specs/tools/t27o/ledger.t27).
T27oSweep { paths: Vec<String>, #[arg(long, default_value_t = t27o_ledger::SWEEP_MAX_BYTES)] max_bytes: usize, #[arg(long, default_value = t27o_ledger::SWEEP_CACHE)] cache: String, #[arg(long, default_value_t = t27o_ledger::SWEEP_TOP)] top: usize },
}

#[derive(Subcommand)]
Expand Down Expand Up @@ -1327,6 +1329,7 @@ fn main() -> Result<()> {
Commands::Hot { t27c, action, rest } => std::process::exit(cmd_hot(action, rest, t27c.as_deref()) as i32),
Commands::Payout { epoch, pool, json } => std::process::exit(payout::cmd(*epoch, *pool, *json)? as i32),
Commands::T27o { file, name, oracle, check, t27c } => std::process::exit(cmd_t27o(file, name.as_deref(), *oracle, *check, t27c.as_deref())? as i32),
Commands::T27oSweep { paths, max_bytes, cache, top } => std::process::exit(cmd_t27o_sweep(paths, *max_bytes, cache, *top)? as i32),
}

Ok(())
Expand Down Expand Up @@ -1358,6 +1361,37 @@ fn cmd_t27o(file: &str, name: Option<&str>, oracle: bool, check: bool, t27c: Opt
Ok(Command::new(mutate::resolve_t27c(t27c)).arg("test-report").arg(&path).status()?.code().unwrap_or(1) as u8)
}

/// `tri t27o-sweep` (#10543): every rule is ledger.t27 (which files, whether a row is reusable, coverage, root vs cascade, the ranking); this lists, hashes, converts in-process and keeps the cache.
fn cmd_t27o_sweep(paths: &[String], max: usize, cache: &str, top: usize) -> Result<u8> {
let t0 = std::time::Instant::now(); let seal = |f: &str| -> Result<String> { Ok(serde_json::from_slice::<serde_json::Value>(&fs::read(f)?)?["spec_hash"].as_str().with_context(|| format!("{f}: no spec_hash"))?.to_string()) };
let (conv, std) = (seal(".trinity/seals/t27o_T27oRust.json")?, seal(".trinity/seals/t27o_T27oRustStd.json")?);
let old: &'static str = fs::read_to_string(cache).unwrap_or_default().leak(); let rows: std::collections::HashMap<&'static str, Vec<&'static str>> = old.lines().map(|l| l.split('\t').collect::<Vec<_>>()).filter(|f| f.len() == 10).map(|f| (f[0], f)).collect();
let listing: &'static str = String::from_utf8(Command::new("git").args(["ls-files", "--"]).args(paths).output()?.stdout)?.leak();
let (mut tab, mut kinds, mut tot, mut n) = (String::new(), std::collections::BTreeMap::<&'static str, usize>::new(), [0usize; 5], [0usize; 3]);
for p in listing.lines().filter(|p| t27o_ledger::sweep_path(p)) {
let Ok(src) = fs::read(p) else { continue };
if t27o_ledger::over_cap(src.len(), max) { n[2] += 1; println!("{p} {} bytes skipped", src.len()); continue; }
let (sha, r) = (format!("{:x}", Sha256::digest(&src)), rows.get(p));
let reuse = t27o_ledger::reuse_row(t27o_ledger::key_check(r.is_some(), r.is_some_and(|r| r[1] == sha), r.is_some_and(|r| r[2] == conv), r.is_some_and(|r| r[3] == std)));
let f: Vec<&'static str> = if reuse { r.unwrap().clone() } else {
let (mut out, mut st, mut k) = (vec![0u8; 1 << 24], vec![0usize; 1 << 16], std::collections::BTreeMap::<&'static str, usize>::new());
let m = t27o::convert(&src, Path::new(p).file_stem().map_or("Converted".into(), |s| s.to_string_lossy().into_owned()).as_bytes(), &mut out, &mut st);
let o: &'static str = String::from_utf8_lossy(&out[..m.min(out.len())]).into_owned().leak(); for l in o.lines().filter(|l| t27o_ledger::is_refusal(l)) { *k.entry(&l[t27o_ledger::kind_from(l)..t27o_ledger::kind_to(l)]).or_default() += 1; }
format!("{p}\t{sha}\t{conv}\t{std}\t{}\t{}\t{}\t{}\t{}\t{}", st[t27o::NFN], st[t27o::NOK], st[t27o::NTEST], st[t27o::NTS], st[t27o::NSTUB], k.iter().map(|(a, b)| format!("{a}={b}")).collect::<Vec<_>>().join(";")).leak().split('\t').collect()
};
n[reuse as usize] += 1; tab += &format!("{}\n", f.join("\t"));
(0..5).for_each(|i| tot[i] += f[4 + i].parse::<usize>().unwrap_or(0));
f[9].split(';').filter_map(|e| e.rsplit_once('=')).for_each(|(k, c)| *kinds.entry(k).or_default() += c.parse::<usize>().unwrap_or(0));
println!("{} {} {} {}/{} {} {}", f[0], f[4], f[5], f[6], f[7], f[8], if reuse { "reused" } else { "fresh" });
}
let cov = t27o_ledger::coverage_permille(tot[0], tot[1]); println!("total {} files {} fn seen {} converted tests {}/{} stubs {} coverage {}", n[0] + n[1], tot[0], tot[1], tot[2], tot[3], tot[4], if t27o_ledger::coverage_known(cov) { format!("{}.{}%", cov / 10, cov % 10) } else { "unknown".into() });
let (casc, mut root): (Vec<_>, Vec<_>) = kinds.into_iter().partition(|(k, _)| t27o_ledger::is_cascade(*k));
root.sort_by(|a, b| t27o_ledger::rank_cmp(a.1, a.0, b.1, b.0).cmp(&0)); root.iter().take(top).for_each(|(k, c)| println!("{c:>7} {k}"));
println!("{:>7} cascade ({})\ncold {} / reused {} / skipped {} wall {:.1} s", casc.iter().map(|k| k.1).sum::<usize>(), t27o_ledger::KIND_CASCADE, n[0], n[1], n[2], t0.elapsed().as_secs_f64());
if let Some(d) = Path::new(cache).parent() { fs::create_dir_all(d)?; }
fs::write(cache, tab)?; Ok(0)
}

/// `tri lanes`: gh's open pull requests into the base, the clone's worktrees and branch times, and what specs/tri/lanes/lanes.t27 reads in them.
fn cmd_lanes(repo: &str, base: &str, clone: &str, dir: &str, stale: u64) -> Result<u8> {
fn run(c: &str, a: &[&str]) -> Result<&'static str> { Ok(String::from_utf8_lossy(&Command::new(c).args(a).output()?.stdout).into_owned().leak()) }
Expand Down
Loading
Loading