mirbuilder: integrate Normalizer (toggle), add tag-quiet mode, share f64 canonicalization; expand canaries; doc updates for quick timeout + dev toggles; Phase 21.5 optimization readiness
This commit is contained in:
@ -6,6 +6,17 @@ use std::sync::{Arc, Mutex, OnceLock};
|
||||
use crate::boxes::file::provider::FileIo;
|
||||
use crate::boxes::file::core_ro::CoreRoFileIo;
|
||||
|
||||
/// Provider selection policy (global). Applied when mode=Auto.
|
||||
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
|
||||
enum ProviderPolicy {
|
||||
/// Current default: prefer plugin/dynamic providers by priority; use ring-1 as fallback
|
||||
StrictPluginFirst,
|
||||
/// Prefer ring-1 (static/core-ro) for stability/CI; fall back to plugin if unavailable
|
||||
SafeCoreFirst,
|
||||
/// Alias to SafeCoreFirst for future extension
|
||||
StaticPreferred,
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
pub enum FileBoxMode { Auto, CoreRo, PluginOnly }
|
||||
|
||||
@ -49,6 +60,15 @@ fn ensure_builtin_file_provider_registered() {
|
||||
}
|
||||
}
|
||||
|
||||
/// Read global provider policy (affects Auto mode only)
|
||||
fn read_provider_policy_from_env() -> ProviderPolicy {
|
||||
match std::env::var("HAKO_PROVIDER_POLICY").unwrap_or_else(|_| "strict-plugin-first".to_string()).as_str() {
|
||||
"safe-core-first" => ProviderPolicy::SafeCoreFirst,
|
||||
"static-preferred" => ProviderPolicy::StaticPreferred,
|
||||
_ => ProviderPolicy::StrictPluginFirst,
|
||||
}
|
||||
}
|
||||
|
||||
/// Read FileBox mode from environment variables
|
||||
#[allow(dead_code)]
|
||||
pub fn read_filebox_mode_from_env() -> FileBoxMode {
|
||||
@ -73,7 +93,8 @@ pub fn select_file_provider(mode: FileBoxMode) -> Arc<dyn FileIo> {
|
||||
|
||||
match mode {
|
||||
FileBoxMode::Auto => {
|
||||
// Try: dynamic/builtin (by priority) → core-ro fallback
|
||||
// Selection by global policy
|
||||
let policy = read_provider_policy_from_env();
|
||||
if let Some(reg) = registry {
|
||||
let mut factories: Vec<_> = reg.lock().unwrap()
|
||||
.iter()
|
||||
@ -81,14 +102,38 @@ pub fn select_file_provider(mode: FileBoxMode) -> Arc<dyn FileIo> {
|
||||
.cloned()
|
||||
.collect();
|
||||
|
||||
// Sort by priority (descending)
|
||||
// Sort by priority (descending); plugin providers should rank higher than ring-1 (priority -100)
|
||||
factories.sort_by(|a, b| b.priority().cmp(&a.priority()));
|
||||
|
||||
if let Some(factory) = factories.first() {
|
||||
if !quiet_pipe {
|
||||
eprintln!("[provider-registry] FileBox: using registered provider (priority={})", factory.priority());
|
||||
// Try policy-driven choice first
|
||||
match policy {
|
||||
ProviderPolicy::StrictPluginFirst => {
|
||||
if let Some(factory) = factories.first() {
|
||||
if !quiet_pipe || std::env::var("HAKO_PROVIDER_TRACE").as_deref() == Ok("1") {
|
||||
eprintln!("[provider-registry] FileBox: using registered provider (priority={})", factory.priority());
|
||||
eprintln!("[provider/select:FileBox ring=plugin src=dynamic]");
|
||||
}
|
||||
return factory.create_provider();
|
||||
}
|
||||
}
|
||||
ProviderPolicy::SafeCoreFirst | ProviderPolicy::StaticPreferred => {
|
||||
// Prefer ring-1 (priority <= -100)
|
||||
if let Some(core_ro) = factories.iter().find(|f| f.priority() <= -100) {
|
||||
if !quiet_pipe || std::env::var("HAKO_PROVIDER_TRACE").as_deref() == Ok("1") {
|
||||
eprintln!("[provider-registry] FileBox: using core-ro (policy)");
|
||||
eprintln!("[provider/select:FileBox ring=1 src=static caps=[read]]");
|
||||
}
|
||||
return core_ro.create_provider();
|
||||
}
|
||||
// Fallback to first available (plugin)
|
||||
if let Some(factory) = factories.first() {
|
||||
if !quiet_pipe || std::env::var("HAKO_PROVIDER_TRACE").as_deref() == Ok("1") {
|
||||
eprintln!("[provider-registry] FileBox: using registered provider (priority={})", factory.priority());
|
||||
eprintln!("[provider/select:FileBox ring=plugin src=dynamic]");
|
||||
}
|
||||
return factory.create_provider();
|
||||
}
|
||||
}
|
||||
return factory.create_provider();
|
||||
}
|
||||
}
|
||||
|
||||
@ -105,11 +150,12 @@ pub fn select_file_provider(mode: FileBoxMode) -> Arc<dyn FileIo> {
|
||||
eprintln!("[failfast/provider/filebox:auto-fallback-blocked]");
|
||||
panic!("Fail-Fast: FileBox provider fallback is disabled (NYASH_FAIL_FAST=0 or NYASH_FILEBOX_ALLOW_FALLBACK=1 to override)");
|
||||
} else {
|
||||
if !quiet_pipe {
|
||||
if !quiet_pipe || std::env::var("HAKO_PROVIDER_TRACE").as_deref() == Ok("1") {
|
||||
eprintln!(
|
||||
"[provider-registry] FileBox: using core-ro fallback{}",
|
||||
if allow_fb_override { " (override)" } else { "" }
|
||||
);
|
||||
eprintln!("[provider/select:FileBox ring=1 src=static caps=[read]]");
|
||||
}
|
||||
Arc::new(CoreRoFileIo::new())
|
||||
}
|
||||
@ -126,8 +172,9 @@ pub fn select_file_provider(mode: FileBoxMode) -> Arc<dyn FileIo> {
|
||||
factories.sort_by(|a, b| b.priority().cmp(&a.priority()));
|
||||
|
||||
if let Some(factory) = factories.first() {
|
||||
if !quiet_pipe {
|
||||
if !quiet_pipe || std::env::var("HAKO_PROVIDER_TRACE").as_deref() == Ok("1") {
|
||||
eprintln!("[provider-registry] FileBox: using plugin-only provider (priority={})", factory.priority());
|
||||
eprintln!("[provider/select:FileBox ring=plugin src=dynamic]");
|
||||
}
|
||||
return factory.create_provider();
|
||||
}
|
||||
@ -137,10 +184,21 @@ pub fn select_file_provider(mode: FileBoxMode) -> Arc<dyn FileIo> {
|
||||
}
|
||||
FileBoxMode::CoreRo => {
|
||||
// Always use core-ro, ignore registry
|
||||
if !quiet_pipe {
|
||||
if !quiet_pipe || std::env::var("HAKO_PROVIDER_TRACE").as_deref() == Ok("1") {
|
||||
eprintln!("[provider-registry] FileBox: using core-ro (forced)");
|
||||
eprintln!("[provider/select:FileBox ring=1 src=static caps=[read]]");
|
||||
}
|
||||
Arc::new(CoreRoFileIo::new())
|
||||
}
|
||||
}
|
||||
}
|
||||
/// Provider descriptor (ring/source/capabilities). Currently informational.
|
||||
#[allow(dead_code)]
|
||||
#[derive(Clone, Debug)]
|
||||
struct ProviderDescriptor {
|
||||
box_name: &'static str,
|
||||
ring: &'static str, // "0" | "1" | "plugin"
|
||||
source: &'static str, // "static" | "dynamic"
|
||||
capabilities: &'static [&'static str], // e.g., ["read"]
|
||||
priority: i32,
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user