* signals: restore the pre-port flag marker emoji
#903 inadvertently replaced the legacy FLAG_MARKER (U+1F6A9, '🚩') with
'[!]', which broke any downstream dashboard / alert that searches span
names for the flag emoji. Restores the original marker and updates the
#910 docs pass to match.
- crates/brightstaff/src/signals/analyzer.rs: FLAG_MARKER back to
"\\u{1F6A9}" with a comment noting the backwards-compatibility
reason so it doesn't drift again.
- docs/source/concepts/signals.rst and docs/source/guides/observability/
tracing.rst: swap every '[!]' reference (subheading text, example
span name, tip box, dashboard query hint) back to 🚩.
Verified: cargo test -p brightstaff --lib (162 passed, 1 ignored);
sphinx-build clean on both files; rendered HTML shows 🚩 in all
flag-marker references.
Made-with: Cursor
* fix: silence manual_checked_ops clippy lint (rustc 1.95)
Pre-existing warning in router/stress_tests.rs that becomes an error
under CI's -D warnings with rustc 1.95. Replace the manual if/else
with growth.checked_div(num_iterations).unwrap_or(0) as clippy
suggests.
Made-with: Cursor
* fix(routing): auto-migrate v0.3.0 inline routing_preferences to v0.4.0 top-level
Lift inline routing_preferences under each model_provider into the
top-level routing_preferences list with merged models[] and bump
version to v0.4.0, with a deprecation warning. Existing v0.3.0
demo configs (Claude Code, Codex, preference_based_routing, etc.)
keep working unchanged. Schema flags the inline shape as deprecated
but still accepts it. Docs and skills updated to canonical top-level
multi-model form.
* test(common): bump reference config assertion to v0.4.0
The rendered reference config was bumped to v0.4.0 when its inline
routing_preferences were lifted to the top level; align the
configuration deserialization test with that change.
* fix(config_generator): bump version to v0.4.0 up front in migration
Move the v0.3.0 -> v0.4.0 version bump to the top of
migrate_inline_routing_preferences so it runs unconditionally,
including for configs that already declare top-level
routing_preferences at v0.3.0. Previously the bump only fired
when inline migration produced entries, leaving top-level v0.3.0
configs rejected by brightstaff's v0.4.0 gate. Tests updated to
cover the new behavior and to confirm we never downgrade newer
versions.
* fix(config_generator): gate routing_preferences migration on version < v0.4.0
Short-circuit the migration when the config already declares v0.4.0
or newer. Anything at v0.4.0+ is assumed to be on the canonical
top-level shape and is passed through untouched, including stray
inline preferences (which are the author's bug to fix). Only v0.3.0
and older configs are rewritten and bumped.
* docs: align signals page with paper taxonomy
Updates docs/source/concepts/signals.rst and the tracing guide's signals
subsection to reflect the three-layer taxonomy shipped in #903:
- Introduces the paper reference (arXiv:2604.00356) and the three layers
(interaction, execution, environment) with all 20 leaf signal types in
three reference tables
- Documents the new layered OTel attribute set
(signals.interaction.*, signals.execution.*, signals.environment.*)
and marks the legacy aggregate keys (signals.follow_up.repair.*,
signals.frustration.*, signals.repetition.count,
signals.escalation.requested, signals.positive_feedback.count) as
deprecated-but-still-emitted
- Adds a Span Events section describing the per-instance signal.<type>
events with confidence / snippet / metadata attributes
- Fixes the flag marker reference ([!] in the code vs 🚩 in the old docs)
- Updates all example attributes, dashboard queries, and alert rules to
use the layered keys
- Updates the tracing guide's behavioral-signals subsection to match
- Notes that the triage sampler is a planned follow-up and today sampling
is consumer-side via observability-platform filters
Build verified locally: sphinx-build produces no warnings on these files.
Made-with: Cursor
* docs: reframe signals intro around the improvement flywheel
Addresses review feedback on #910:
- Replace the triage-only framing at the top with an instrument -> sample
& triage -> construct data -> optimize -> deploy flywheel that explains
why signals matter, not just what they surface. Paper's 82% / 1.52x
numbers move into step 2 of the flywheel where they belong.
- Remove the 'Signals vs Response Quality' section. Per review, signals
and response quality overlap rather than complement each other, so the
comparison is misleading.
- Borrow the per-category summaries and leaf-type descriptions verbatim
from the katanemo/signals reference implementation (module docstrings)
so the documentation and the detector contract stay in sync. Drops the
hand-crafted examples that were not strictly accurate (e.g. 'semantic
overlap is high' for rephrase, 'user explicitly corrects the agent'
for correction).
Made-with: Cursor
* docs: address signals flywheel review feedback
Addresses review comments on #910:
- Shorten the paper citation to (Chen et al., 2026) per common cite
practice (replacing the full author list form).
- Replace the Why Signals Matter section with the review-suggested
rewrite verbatim: more formal intro framing, renumbered steps to
Instrument / Sample & triage / Data Construction / Model Optimization
/ Deploy, removes 'routing decisions' from the data-construction
step, and adds DPO/RLHF/SFT as model-optimization examples.
- Renders tau and O(messages) as proper math glyphs via the sphinx
built-in :math: role (enabled by adding sphinx.ext.mathjax to
conf.py). Using the RST role form rather than raw $...$ inline so
sphinx only injects MathJax on pages that actually have math,
instead of loading ~1MB of JS on every page.
Build verified locally: sphinx-build produces no warnings on the
changed files and the rendered HTML wraps tau and O(messages) in
MathJax-ready <span class="math">\(\tau\)</span> containers.
Made-with: Cursor
* add pluggable session cache with Redis backend
* add Redis session affinity demos (Docker Compose and Kubernetes)
* address PR review feedback on session cache
* document Redis session cache backend for model affinity
* sync rendered config reference with session_cache addition
* add tenant-scoped Redis session cache keys and remove dead log_affinity_hit
- Add tenant_header to SessionCacheConfig; when set, cache keys are scoped
as plano:affinity:{tenant_id}:{session_id} for multi-tenant isolation
- Thread tenant_id through RouterService, routing_service, and llm handlers
- Use Cow<'_, str> in session_key to avoid allocation when no tenant is set
- Remove unused log_affinity_hit (logging was already inlined at call sites)
* remove session_affinity_redis and session_affinity_redis_k8s demos
* feat(provider): add xiaomi as first-class provider
* feat(demos): add xiaomi mimo integration demo
* refactor(demos): remove Xiaomi MiMo integration demo and update documentation
* updating model list and adding the xiamoi models
---------
Co-authored-by: Salman Paracha <salmanparacha@MacBook-Pro-389.local>
* feat(web): announce DigitalOcean acquisition across sites
* fix(web): make blog routes resilient without Sanity config
* fix(web): add mobile arrow cue to announcement banner
* fix(web): point acquisition links to announcement post
* support configurable orchestrator model via orchestration config section
* add self-hosting docs and demo for Plano-Orchestrator
* list all Plano-Orchestrator model variants in docs
* use overrides for custom routing and orchestration model
* update docs
* update orchestrator model name
* rename arch provider to plano, use llm_routing_model and agent_orchestration_model
* regenerate rendered config reference