refactor(task_gate): Phase B language-advantage pass — dichotomy wave
CI Pipeline / best-practices (push) Successful in 7s
CI Pipeline / documentation (push) Successful in 7s
CI Pipeline / rust-surface (push) Failing after 14s
CI Pipeline / required-checks (push) Canceled after 0s
CI Pipeline / CI Pipeline / notify-event-bridge (push) Canceled after 0s
CI Pipeline / go-surface (push) Canceled after 17s
CI Pipeline / canary (push) Canceled after 20s
CI Pipeline / type-check (push) Canceled after 11s
CI Pipeline / gitea-offline (push) Canceled after 10s
Auto-version and Release / release (push) Canceled after 27s
deploy / deploy (push) Canceled after 6s
CI Pipeline / unit-tests (push) Canceled after 25s
CI Pipeline / lint (push) Canceled after 26s
CI Pipeline / best-practices (push) Successful in 7s
CI Pipeline / documentation (push) Successful in 7s
CI Pipeline / rust-surface (push) Failing after 14s
CI Pipeline / required-checks (push) Canceled after 0s
CI Pipeline / CI Pipeline / notify-event-bridge (push) Canceled after 0s
CI Pipeline / go-surface (push) Canceled after 17s
CI Pipeline / canary (push) Canceled after 20s
CI Pipeline / type-check (push) Canceled after 11s
CI Pipeline / gitea-offline (push) Canceled after 10s
Auto-version and Release / release (push) Canceled after 27s
deploy / deploy (push) Canceled after 6s
CI Pipeline / unit-tests (push) Canceled after 25s
CI Pipeline / lint (push) Canceled after 26s
This commit is contained in:
1 parent
b20a74badb
commit
fa72a60d95
1 file changed
+137
-42
+137
-42
@@ -156,12 +156,83 @@ fn py_regex_matches(pattern: &str, text: &str) -> bool {
|
||||
.unwrap_or(false)
|
||||
}
|
||||
|
||||
fn row_str<'a>(row: &'a Value, key: &str) -> &'a str {
|
||||
row.get(key).and_then(Value::as_str).unwrap_or("")
|
||||
// ── typed row boundary (Phase B) ─────────────────────────────────────────────
|
||||
|
||||
/// The oracle's status lattice. Rows carry free-text statuses (sqlite TEXT),
|
||||
/// so the lattice is open at the tail — but every comparison the oracle
|
||||
/// makes (`!= 'retired'` in record, `== 'active'` in check) is exhaustive
|
||||
/// here, and `Other` keeps unknown values pass-through exactly like the
|
||||
/// oracle's string comparisons do.
|
||||
enum GateStatus<'a> {
|
||||
Observing,
|
||||
Active,
|
||||
Retired,
|
||||
/// Any non-lattice TEXT value: consulted by record (the oracle only
|
||||
/// excludes 'retired') and ignored by check (only 'active' projects).
|
||||
Other(#[allow(dead_code)] &'a str),
|
||||
}
|
||||
|
||||
fn row_i64(row: &Value, key: &str) -> i64 {
|
||||
row.get(key).and_then(Value::as_i64).unwrap_or(0)
|
||||
impl GateStatus<'_> {
|
||||
fn parse(s: &str) -> GateStatus<'_> {
|
||||
match s {
|
||||
"observing" => GateStatus::Observing,
|
||||
"active" => GateStatus::Active,
|
||||
"retired" => GateStatus::Retired,
|
||||
other => GateStatus::Other(other),
|
||||
}
|
||||
}
|
||||
|
||||
/// record_instruction consults non-retired rows only.
|
||||
fn is_matchable(&self) -> bool {
|
||||
!matches!(self, GateStatus::Retired)
|
||||
}
|
||||
|
||||
/// check_context projects active rows only.
|
||||
fn is_active(&self) -> bool {
|
||||
matches!(self, GateStatus::Active)
|
||||
}
|
||||
}
|
||||
|
||||
/// Borrowed, typed view of one instruction row — zero-copy &str accessors
|
||||
/// over the facade's row doc (Phase B: no per-row String churn).
|
||||
struct GateRow<'a> {
|
||||
id: i64,
|
||||
pattern: &'a str,
|
||||
instruction: &'a str,
|
||||
count: i64,
|
||||
threshold: i64,
|
||||
status: GateStatus<'a>,
|
||||
}
|
||||
|
||||
impl GateRow<'_> {
|
||||
fn from_doc(row: &Value) -> GateRow<'_> {
|
||||
let s = |k: &str| row.get(k).and_then(Value::as_str).unwrap_or("");
|
||||
GateRow {
|
||||
id: row.get("id").and_then(Value::as_i64).unwrap_or(0),
|
||||
pattern: s("pattern"),
|
||||
instruction: s("instruction"),
|
||||
count: row.get("count").and_then(Value::as_i64).unwrap_or(0),
|
||||
threshold: row.get("threshold").and_then(Value::as_i64).unwrap_or(0),
|
||||
status: GateStatus::parse(s("status")),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// The record verdict before JSON rendering (Phase B: the decision lattice
|
||||
/// is an enum, the boundary match is exhaustive).
|
||||
enum RecordVerdict<'a> {
|
||||
Matched {
|
||||
id: i64,
|
||||
new_count: i64,
|
||||
promoted: bool,
|
||||
new_status: &'static str,
|
||||
now: &'a str,
|
||||
},
|
||||
NewRow {
|
||||
instruction: &'a str,
|
||||
pattern: String,
|
||||
now: &'a str,
|
||||
},
|
||||
}
|
||||
|
||||
// ── public functions (name-preserving ports of the oracle) ──────────────────
|
||||
@@ -175,41 +246,64 @@ pub fn record_instruction(rows: &[Value], text: &str, now: &str) -> Value {
|
||||
let lowered = text.to_lowercase();
|
||||
let lowered = lowered.trim();
|
||||
|
||||
for row in rows {
|
||||
if row_str(row, "status") == "retired" {
|
||||
continue;
|
||||
}
|
||||
if py_regex_matches(row_str(row, "pattern"), lowered) {
|
||||
let new_count = row_i64(row, "count") + 1;
|
||||
let status = row_str(row, "status");
|
||||
let new_status = if new_count >= row_i64(row, "threshold") {
|
||||
"active"
|
||||
} else {
|
||||
"observing"
|
||||
};
|
||||
return json!({
|
||||
"matched": true,
|
||||
"id": row_i64(row, "id"),
|
||||
"count": new_count,
|
||||
"status": new_status,
|
||||
"promoted": new_status == "active" && status != "active",
|
||||
"last_seen": now,
|
||||
});
|
||||
}
|
||||
}
|
||||
let verdict = rows
|
||||
.iter()
|
||||
.map(GateRow::from_doc)
|
||||
.find(|row| row.status.is_matchable() && py_regex_matches(row.pattern, lowered))
|
||||
.map(|row| match row.count + 1 >= row.threshold {
|
||||
true => RecordVerdict::Matched {
|
||||
id: row.id,
|
||||
new_count: row.count + 1,
|
||||
promoted: !matches!(row.status, GateStatus::Active),
|
||||
new_status: "active",
|
||||
now,
|
||||
},
|
||||
false => RecordVerdict::Matched {
|
||||
id: row.id,
|
||||
new_count: row.count + 1,
|
||||
promoted: false,
|
||||
new_status: "observing",
|
||||
now,
|
||||
},
|
||||
})
|
||||
.unwrap_or_else(|| RecordVerdict::NewRow {
|
||||
instruction: text,
|
||||
pattern: extract_pattern(lowered),
|
||||
now,
|
||||
});
|
||||
|
||||
json!({
|
||||
"matched": false,
|
||||
"new_row": {
|
||||
"instruction": text,
|
||||
"pattern": extract_pattern(lowered),
|
||||
"count": 1,
|
||||
"threshold": 3,
|
||||
"status": "observing",
|
||||
"created_at": now,
|
||||
match verdict {
|
||||
RecordVerdict::Matched {
|
||||
id,
|
||||
new_count,
|
||||
promoted,
|
||||
new_status,
|
||||
now,
|
||||
} => json!({
|
||||
"matched": true,
|
||||
"id": id,
|
||||
"count": new_count,
|
||||
"status": new_status,
|
||||
"promoted": promoted,
|
||||
"last_seen": now,
|
||||
},
|
||||
})
|
||||
}),
|
||||
RecordVerdict::NewRow {
|
||||
instruction,
|
||||
pattern,
|
||||
now,
|
||||
} => json!({
|
||||
"matched": false,
|
||||
"new_row": {
|
||||
"instruction": instruction,
|
||||
"pattern": pattern,
|
||||
"count": 1,
|
||||
"threshold": 3,
|
||||
"status": "observing",
|
||||
"created_at": now,
|
||||
"last_seen": now,
|
||||
},
|
||||
}),
|
||||
}
|
||||
}
|
||||
|
||||
/// task_gate.check_context — project the ACTIVE gates whose pattern matches
|
||||
@@ -220,13 +314,14 @@ pub fn check_context(rows: &[Value], context: &str) -> Value {
|
||||
let lowered = context.to_lowercase();
|
||||
let matches: Vec<Value> = rows
|
||||
.iter()
|
||||
.filter(|row| row_str(row, "status") == "active")
|
||||
.filter(|row| py_regex_matches(row_str(row, "pattern"), &lowered))
|
||||
.map(GateRow::from_doc)
|
||||
.filter(|row| row.status.is_active())
|
||||
.filter(|row| py_regex_matches(row.pattern, &lowered))
|
||||
.map(|row| {
|
||||
json!({
|
||||
"id": row_i64(row, "id"),
|
||||
"instruction": row_str(row, "instruction"),
|
||||
"count": row_i64(row, "count"),
|
||||
"id": row.id,
|
||||
"instruction": row.instruction,
|
||||
"count": row.count,
|
||||
})
|
||||
})
|
||||
.collect();
|
||||
|
||||
Reference in new issue
Block a user