refactor(drift_ledger): Phase B language-advantage pass — dichotomy wave
CI Pipeline / best-practices (push) Successful in 10s
CI Pipeline / documentation (push) Successful in 4s
CI Pipeline / rust-surface (push) Failing after 17s
CI Pipeline / go-surface (push) Failing after 20s
CI Pipeline / required-checks (push) Canceled after 0s
CI Pipeline / CI Pipeline / notify-event-bridge (push) Canceled after 0s
Auto-version and Release / release (push) Canceled after 36s
CI Pipeline / gitea-offline (push) Canceled after 18s
CI Pipeline / lint (push) Canceled after 36s
CI Pipeline / type-check (push) Canceled after 22s
CI Pipeline / unit-tests (push) Canceled after 35s
CI Pipeline / canary (push) Canceled after 36s
deploy / deploy (push) Canceled after 39s

Language-advantage pass on the drift_ledger Rust kernel (battery green
throughout, live parity re-verified 87/87 byte-identical after rebuild):
- Block lattice is a real enum (Constitution..Project) with as_str/of_name/
  limit matches — the constitution's stricter limit and its ANY-content-
  change strict check are exhaustive matches, not string compares; the
  per-block alert loop and snapshot assembly iterate BlockLabel::ALL.
- check_alerts is iterator-composed: BlockLabel::ALL.filter_map over the
  baseline decision, emitting alerts via then(..) — the python loop's
  anchor-vs-snapshot branch stays a plain match.
- diff_blocks is zero-copy iterator composition (filter_map + take(6)/
  take(3) replaces the manual capped pushes); the whitespace-significance
  filter is one shared fn item over &str slices.
- All keyword tables and contents borrow (&str / &Value) end-to-end — no
  per-block copying or lowering.
- Frozen DL truth replay untouched and VERBATIM (branch_battery.rs replays
  the same 87-case oracle truth).
This commit is contained in:
Nick committed 2026-10-12 14:33:28 +01:00
1 parent c0ec3135c6
commit 62e47b3812
1 file changed
+112 -65
+112 -65
View File
@@ -14,7 +14,49 @@ use std::os::raw::c_char;
pub const DRIFT_LIMIT: f64 = 0.30;
pub const CONSTITUTION_LIMIT: f64 = 0.05;
pub const BLOCKS: &[&str] = &["constitution", "persona", "human", "operating", "project"];
/// The five guarded blocks — a closed lattice, not stringly-typed routing.
/// The constitution's limit is exhaustive-match derived; every other block
/// falls to the plain drift limit (the oracle's ternary).
#[derive(Clone, Copy, PartialEq, Eq, Debug)]
pub enum BlockLabel {
Constitution,
Persona,
Human,
Operating,
Project,
}
impl BlockLabel {
pub const ALL: [BlockLabel; 5] = [
Self::Constitution,
Self::Persona,
Self::Human,
Self::Operating,
Self::Project,
];
pub fn as_str(self) -> &'static str {
match self {
Self::Constitution => "constitution",
Self::Persona => "persona",
Self::Human => "human",
Self::Operating => "operating",
Self::Project => "project",
}
}
pub fn of_name(name: &str) -> Option<Self> {
Self::ALL.iter().copied().find(|b| b.as_str() == name)
}
pub fn limit(self) -> f64 {
match self {
Self::Constitution => CONSTITUTION_LIMIT,
_ => DRIFT_LIMIT,
}
}
}
/// _sha port: hex sha256 of UTF-8 text.
pub fn sha(text: &str) -> String {
@@ -28,28 +70,28 @@ pub fn diff_blocks(reference: &str, current: &str) -> String {
if reference.is_empty() {
return "no prior content (first drift from empty baseline)".to_string();
}
fn sig(l: &str) -> Option<&str> {
let s = l.trim();
(!s.is_empty()).then_some(s)
}
let ref_lines: Vec<&str> = reference.lines().collect();
let cur_lines: Vec<&str> = current.lines().collect();
let ref_set: std::collections::HashSet<&str> =
ref_lines.iter().filter_map(|l| { let s = l.trim(); if s.is_empty() { None } else { Some(s) } }).collect();
ref_lines.iter().filter_map(|l| sig(l)).collect();
let cur_set: std::collections::HashSet<&str> =
cur_lines.iter().filter_map(|l| { let s = l.trim(); if s.is_empty() { None } else { Some(s) } }).collect();
let mut added: Vec<&str> = vec![];
for l in &cur_lines {
let s = l.trim();
if !s.is_empty() && !ref_set.contains(s) {
added.push(s);
if added.len() >= 6 { break; }
}
}
let mut removed: Vec<&str> = vec![];
for l in &ref_lines {
let s = l.trim();
if !s.is_empty() && !cur_set.contains(s) {
removed.push(s);
if removed.len() >= 3 { break; }
}
}
cur_lines.iter().filter_map(|l| sig(l)).collect();
let added: Vec<&str> = cur_lines
.iter()
.filter_map(|l| sig(l))
.filter(|s| !ref_set.contains(*s))
.take(6)
.collect();
let removed: Vec<&str> = ref_lines
.iter()
.filter_map(|l| sig(l))
.filter(|s| !cur_set.contains(*s))
.take(3)
.collect();
let mut parts: Vec<String> = vec![];
if !added.is_empty() {
parts.push(format!(
@@ -85,8 +127,9 @@ pub fn check_block(
None => (prev_size.max(1), None, cur_size - prev_size),
};
let pct = (delta.abs() as f64) / (base.max(1) as f64);
let limit = if label == "constitution" { CONSTITUTION_LIMIT } else { DRIFT_LIMIT };
let content_changed = label == "constitution"
let is_constitution = matches!(BlockLabel::of_name(label), Some(BlockLabel::Constitution));
let limit = if is_constitution { CONSTITUTION_LIMIT } else { DRIFT_LIMIT };
let content_changed = is_constitution
&& anchor_size.is_some()
&& base_sha.is_some()
&& cur_sha.is_some()
@@ -100,7 +143,8 @@ pub fn check_block(
/// auto_fix routing port: (label, anchored, has_last_good) -> {action, reason}.
pub fn auto_fix_decision(label: &str, anchored: bool, has_last_good: bool) -> Value {
if label == "constitution" {
let is_constitution = matches!(BlockLabel::of_name(label), Some(BlockLabel::Constitution));
if is_constitution {
json!({"action": "alert-only", "reason": "constitution changes only by explicit directive; needs human review"})
} else if anchored {
json!({"action": "re-anchored", "reason": "anchored block grew (authorised) — re-baselined"})
@@ -128,12 +172,13 @@ pub fn ledger_path_for(index_file: &str) -> String {
/// snapshot() entry-assembly port: {"when", "blocks": {label: {sha, size,
/// content}}}. "size" is the oracle's len(raw) — a CHARACTER count, not bytes.
/// Unknown labels in the payload are ignored (the oracle iterates BLOCKS).
pub fn snapshot_entry(blocks: &Value, when: &str) -> Value {
let mut b = serde_json::Map::new();
for label in BLOCKS {
let raw = blocks.get(*label).and_then(|v| v.as_str()).unwrap_or("");
for label in BlockLabel::ALL {
let raw = blocks.get(label.as_str()).and_then(|v| v.as_str()).unwrap_or("");
b.insert(
(*label).to_string(),
label.as_str().to_string(),
json!({
"sha": sha(raw),
"size": raw.chars().count(),
@@ -170,46 +215,48 @@ pub fn check_alerts(ledger: &Value, blocks: &Value) -> Value {
.cloned()
.unwrap_or_else(|| json!({}));
let anchors = ledger.get("anchors").cloned().unwrap_or_else(|| json!({}));
let mut alerts: Vec<Value> = vec![];
for label in BLOCKS {
let cur = blocks.get(*label).and_then(|v| v.as_str()).unwrap_or("");
let cur_size = cur.chars().count() as i64;
let anchor_meta = anchors.get(*label);
let (base, base_sha, delta, ref_content) = match anchor_meta {
Some(a) => {
let b = a.get("size").and_then(|v| v.as_i64()).unwrap_or(cur_size);
let sh = a.get("sha").and_then(|v| v.as_str());
let rc = a.get("content").and_then(|v| v.as_str());
(b, sh, cur_size - b, rc)
}
None => {
let pm = prev.get(*label);
let ps = pm
.and_then(|m| m.get("size"))
.and_then(|v| v.as_i64())
.unwrap_or(cur_size);
let rc = pm.and_then(|m| m.get("content")).and_then(|v| v.as_str());
(ps.max(1), None, cur_size - ps, rc)
}
};
let pct = (delta.abs() as f64) / (base.max(1) as f64);
let limit = if *label == "constitution" { CONSTITUTION_LIMIT } else { DRIFT_LIMIT };
let content_changed = *label == "constitution"
&& anchor_meta.is_some()
&& base_sha.is_some()
&& sha(cur) != base_sha.unwrap();
if content_changed || pct > limit {
alerts.push(json!({
"label": label,
"delta": delta,
"pct": py_round3(pct),
"limit": py_round3(limit),
"base": base,
"changed": diff_blocks(ref_content.unwrap_or(""), cur),
"content_changed": content_changed,
}));
}
}
let alerts: Vec<Value> = BlockLabel::ALL
.iter()
.filter_map(|label| {
let cur = blocks.get(label.as_str()).and_then(|v| v.as_str()).unwrap_or("");
let cur_size = cur.chars().count() as i64;
let anchor_meta = anchors.get(label.as_str());
let (base, base_sha, delta, ref_content) = match anchor_meta {
Some(a) => {
let b = a.get("size").and_then(|v| v.as_i64()).unwrap_or(cur_size);
let sh = a.get("sha").and_then(|v| v.as_str());
let rc = a.get("content").and_then(|v| v.as_str());
(b, sh, cur_size - b, rc)
}
None => {
let pm = prev.get(label.as_str());
let ps = pm
.and_then(|m| m.get("size"))
.and_then(|v| v.as_i64())
.unwrap_or(cur_size);
let rc = pm.and_then(|m| m.get("content")).and_then(|v| v.as_str());
(ps.max(1), None, cur_size - ps, rc)
}
};
let pct = (delta.abs() as f64) / (base.max(1) as f64);
let limit = label.limit();
let content_changed = matches!(label, BlockLabel::Constitution)
&& anchor_meta.is_some()
&& base_sha.is_some()
&& sha(cur) != base_sha.unwrap();
(content_changed || pct > limit).then(|| {
json!({
"label": label.as_str(),
"delta": delta,
"pct": py_round3(pct),
"limit": py_round3(limit),
"base": base,
"changed": diff_blocks(ref_content.unwrap_or(""), cur),
"content_changed": content_changed,
})
})
})
.collect();
Value::Array(alerts)
}