Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
94 commits
Select commit Hold shift + click to select a range
c37ab7b
Merge remote-tracking branch 'origin/predev' into p3-flip-llm
MattJackson Oct 4, 2026
fbec053
FLIP-LLM kernel: the far end's hook overrides on the kernel's own egr…
MattJackson Oct 4, 2026
7bb6a9c
FLIP-LLM plane: the llm plane's `project` binding and exchange/projec…
MattJackson Oct 4, 2026
826d1fa
FLIP-LLM serve path: under the `llm-on-driver` switch the llm door is…
MattJackson Oct 4, 2026
3227969
FLIP-LLM: the test plane refuses only a refusal with no reason or no …
MattJackson Oct 4, 2026
c1b8c4c
FLIP-LLM gates: the design-bindings citations of the 1.5.5 hook tests…
MattJackson Oct 4, 2026
ccea906
Merge remote-tracking branch 'origin/predev' into p3-flip-llm
MattJackson Oct 4, 2026
5a855a1
Merge remote-tracking branch 'origin/p3-serve-hookstage' into p3-flip…
MattJackson Oct 4, 2026
56032c7
Merge remote-tracking branch 'origin/predev' into p3-flip-llm
MattJackson Oct 4, 2026
3126c2b
Merge remote-tracking branch 'origin/predev' into p3-flip-llm
MattJackson Oct 5, 2026
13bdeef
oracle register: the PLANELOG accepted difference (egress.image-detai…
MattJackson Oct 5, 2026
9eb179c
FLIP-LLM money: the llm plane declares its per-request fee unit and r…
MattJackson Oct 5, 2026
49de832
LLM-UA on the door (OWNER RULING Q10; PROTO-FIXES 0ac5fc9826 already …
MattJackson Oct 5, 2026
5816b1e
DECL-FOLD on the llm flip: every door plane's Statement folds into th…
MattJackson Oct 5, 2026
e35bcda
FLIP-LLM K7: the door-served llm runs 1.5.5's active health probes th…
MattJackson Oct 5, 2026
c20c368
llm plane: `accept` is busbar's own on every far request (transport n…
MattJackson Oct 5, 2026
89926b6
money census: the hook stage's carried refusal site is pinned once (t…
MattJackson Oct 5, 2026
19d7f78
gates on the flip's latest ports: the two boot-time leaks DECL-FOLD m…
MattJackson Oct 5, 2026
b42ddc8
FLIP-LLM deny fixes (hop 37251900048): every feature leg compiles, th…
MattJackson Oct 5, 2026
9ac82ae
Merge remote-tracking branch 'origin/predev' into p3-flip-llm
MattJackson Oct 5, 2026
9c07190
DECL-FOLD: the door rows bind on the process's one dispatcher (booted…
MattJackson Oct 5, 2026
479f32d
Merge origin/p3-seam-ledger into p3-flip-llm: the shared plane ABI un…
MattJackson Oct 5, 2026
217decd
Merge origin/p3-seam-ledger (930d546b16, SEAM-L(r)): the plane cancel…
MattJackson Oct 5, 2026
6f6b8d2
llm codec: an echoed request default is no unrepresentable control (A…
MattJackson Oct 5, 2026
5158a31
fmt; the plane_driver test imports no unused refusal cause
MattJackson Oct 5, 2026
c515ae2
U14: the door serving the pools map witnesses its capability column (…
MattJackson Oct 5, 2026
dee055c
Merge origin/p3-seam-ledger (9f49ae2df1): the reachability door-row a…
MattJackson Oct 5, 2026
5adccc3
Merge remote-tracking branch 'origin/p3-seam-ledger' into p3-flip-llm
MattJackson Oct 5, 2026
522074f
Merge remote-tracking branch 'origin/predev' into p3-flip-llm
MattJackson Oct 5, 2026
46019c3
census pin follows the teller (no Refusal::new site there since SEAM-…
MattJackson Oct 5, 2026
352aed6
serve: the unit handler admits an anonymous caller on the pools-map p…
MattJackson Oct 5, 2026
b88d799
dialect compiler refuses a repeated key; openai_responses.toml states…
MattJackson Oct 5, 2026
0c4e500
Merge origin/p3-seam-ledger (88d7567172): the refusal-site pin follow…
MattJackson Oct 5, 2026
580d9ce
Merge origin/predev (5489d5f615: #465 t-config, DF-SITES kind breakin…
MattJackson Oct 5, 2026
25cce73
root serve test: the records-attach store is the in-memory row config…
MattJackson Oct 5, 2026
d0cd917
llm plane: a pools section dealt alone (stage 3g, #465) is not judged…
MattJackson Oct 5, 2026
981c32b
Merge remote-tracking branch 'origin/p3-seam-ledger' into p3-flip-llm
MattJackson Oct 5, 2026
fca5772
WIP: door-path gaps (ARCHITECT Q128): the dropped-controls audit row …
MattJackson Oct 5, 2026
5ac44bb
Merge remote-tracking branch 'origin/predev' into p3-flip-llm
MattJackson Oct 5, 2026
259a3f7
WIP: the door unit's far end hands the hook stage the walk's candidat…
MattJackson Oct 5, 2026
2a9fa1f
fmt
MattJackson Oct 5, 2026
9772233
Merge origin/p3-plane-fault (4348d899b5): OnPieceOut carries the plan…
MattJackson Oct 5, 2026
601c491
llm plane: on_piece states the breaker's fault reading apart from its…
MattJackson Oct 5, 2026
b3f02a5
U11 port: a body-model caller's smuggled router key never reaches the…
MattJackson Oct 5, 2026
56bbad9
plane ABI: ArriveOut states ROUTE_STREAM and an opaque sticky-routing…
MattJackson Oct 5, 2026
eafda77
WIP: the door routes on what the plane states at arrive (ARCHITECT Q1…
MattJackson Oct 5, 2026
22ae1ce
llm plane: a caller that leaves a usable partial answer cancels OK_PA…
MattJackson Oct 5, 2026
39fb96f
Merge remote-tracking branch 'origin/predev' into p3-flip-llm
MattJackson Oct 5, 2026
856c979
door: the store door's tuple index after predev's LinkedStore reshape…
MattJackson Oct 6, 2026
8ee1590
Merge remote-tracking branch 'origin/predev' into p3-flip-llm
MattJackson Oct 6, 2026
fe388ac
Merge remote-tracking branch 'origin/p3-plane-fault' into p3-flip-llm
MattJackson Oct 6, 2026
ecf7fa7
Merge remote-tracking branch 'origin/predev' into p3-flip-llm
MattJackson Oct 6, 2026
ee66954
Merge remote-tracking branch 'origin/predev' into p3-flip-llm
MattJackson Oct 6, 2026
1068a2f
Merge remote-tracking branch 'origin/p3-plane-fault' into p3-flip-llm
MattJackson Oct 6, 2026
b639fc1
door: seal_live takes the plane's breaker fact as its eighth argument…
MattJackson Oct 6, 2026
4daf05a
Merge remote-tracking branch 'origin/predev' into m-p3-flip-llm
MattJackson Oct 6, 2026
e000a01
Merge remote-tracking branch 'origin/predev' into m464
MattJackson Oct 7, 2026
5b025c5
Merge origin/predev (d5b3712085: #500, #508, #476 host services) into…
MattJackson Oct 7, 2026
8b59f76
kernel: a session's hook stage carries the dialect its unit arrived i…
MattJackson Oct 7, 2026
41e44dd
Merge origin/predev (4b057290d5: #471 salvage LEDGER-100 open classes…
MattJackson Oct 7, 2026
2d83038
Merge origin/predev (d07eaf7e21: #497 decisions flip, #467 D4 moves, …
MattJackson Oct 7, 2026
b1839df
Merge origin/predev (2bbe362dbd: #499 kernel approve) into p3-flip-ll…
MattJackson Oct 7, 2026
61fec31
Merge origin/predev (62a33360d0: #484 auth crates extracted, #543) in…
MattJackson Oct 7, 2026
02d8d72
oauth pin: b7d15c7 + the compiled_in entry (auth-oauth p3-flip-llm-pi…
MattJackson Oct 7, 2026
3bb3b4a
Merge origin/predev (fb5f12aa54: #511 mcp door, #547) into p3-flip-ll…
MattJackson Oct 7, 2026
e5d118d
root tests after the #511 merge: predev's node-hooks arm pins the wal…
MattJackson Oct 7, 2026
60157df
mcp door: an exhausted walk's refusal says the reason's own word, as …
MattJackson Oct 7, 2026
4635be2
plane_integration: the body-ingress convenience routes are mounted, g…
MattJackson Oct 7, 2026
9a918bf
mcp door: the open breaker's word is the door's own constant, so the …
MattJackson Oct 7, 2026
107781c
root tests: the tool door's refusal words for an exhausted walk are f…
MattJackson Oct 7, 2026
3ee9c7a
Merge origin/predev (41f2dc1f78: 78cf7b5839 unit.nest binds the paren…
MattJackson Oct 7, 2026
15c3561
Merge origin/predev (2bf9d9b376: #535 and the routed hook order, U22)…
MattJackson Oct 8, 2026
6d28214
Merge origin/predev (7d04bf0c93: #487 the auth split, #589, #594-#600…
MattJackson Oct 8, 2026
6f49746
Merge origin/predev (39374ec00e) into p3-flip-llm: keep the branch's …
MattJackson Oct 9, 2026
1b85fd9
Merge remote-tracking branch 'origin/predev' into p3-flip-llm
MattJackson Oct 9, 2026
723188d
Fix PR 464 reds: PlaneRegistration fallback field, duplicate dialect …
MattJackson Oct 10, 2026
e2299f7
Merge remote-tracking branch 'origin/predev' into p3-flip-llm
MattJackson Oct 10, 2026
0c3aa99
Merge origin/predev into p3-flip-llm
MattJackson Oct 10, 2026
85ca2a3
Give the healthz door's PlaneRegistration its fallback field
MattJackson Oct 10, 2026
86221f6
Merge remote-tracking branch 'origin/predev' into p3-flip-llm
MattJackson Oct 10, 2026
a495da0
Merge origin/predev into p3-flip-llm
MattJackson Oct 10, 2026
5cec7a0
FLIP-LLM law0: the composition root names no plane, dialect or wire; …
MattJackson Oct 10, 2026
fabf44c
FLIP-LLM reds: the kernel's plane row gives its slack back; the popul…
MattJackson Oct 10, 2026
2f1fcb1
Merge branch 'predev' into p3-flip-llm
MattJackson Oct 10, 2026
18ee8f6
Merge origin/predev (17b55f973b) into p3-flip-llm: the tracing floor …
MattJackson Oct 10, 2026
7a157ea
FLIP-LLM: the kernel's plane row stays at predev's 1175
MattJackson Oct 10, 2026
344b390
Merge origin/predev (477c11d3d9) into p3-flip-llm: the seal keeps bot…
MattJackson Oct 11, 2026
c3a7bc5
busbar tests: DoorReach gets models: None; provider_routes takes the …
MattJackson Oct 12, 2026
a5cb1eb
Merge origin/predev (1617e9f019) into p3-flip-llm: the mcp door keeps…
MattJackson Oct 12, 2026
35c3f18
kernel plane_driver: predev's unpresentable-credential cell after the…
MattJackson Oct 12, 2026
6200ab3
mcp tasks: a terminal state the instance holds and still owes the hos…
MattJackson Oct 12, 2026
47d556f
secret-source scan: the door serving the pools map is driven under th…
MattJackson Oct 12, 2026
665f7bb
Merge origin/predev (8777b2bd1f: #712 the root crate's no-silent-skip…
MattJackson Oct 12, 2026
561c69a
Merge origin/predev (62fdbdf3bc: #665 the gate-first stage binds over…
MattJackson Oct 12, 2026
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
11 changes: 6 additions & 5 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -661,13 +661,14 @@ silently lost every counter. Reaching a recorder is no longer representable from
host accepts only the current one. A sink that wants the observability back-channel implements one
defaulted SDK method, `drain_observations`.

**A new `plugins.logs` block is accepted and checked; plugin log lines have not moved.** The block
**A new `plugins.logs` block is accepted and checked, and plugin log lines move to per-plugin log files.** The block
names the directory for per-plugin log files (`dir`, default `logs/plugins`), the default level
(`level`, default `info`), per-instance levels (`levels`), and rotation (`rotate_mb` and `keep`).
A level word that names no level, or a `rotate_mb` of `0`, refuses the boot and names the key. This
build writes no per-plugin log file: the plugins it loads do not run through the path that writes
them, so a plugin's log lines reach the Busbar log exactly as they did in 1.5.5, and setting
`plugins.logs` changes nothing an operator can observe beyond that check.
A level word that names no level, or a `rotate_mb` of `0`, refuses the boot and names the key.

- 1.6.0 Changed: a plugin's log lines, the LLM plane's included (it is a plugin in 1.6.0), are written to that plugin's own log file under `plugins.logs.dir` (for example `logs/plugins/llm.log`), not to the Busbar log.
In 1.5.5 the plane's warnings (for example `dropping image_url.detail: ...`) were lines of the
Busbar log. **Migration:** point log collection at `plugins.logs.dir` as well as the Busbar log.

### Spec fidelity

Expand Down
8 changes: 4 additions & 4 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions crates/busbar-contract/include/busbar_plugin.h
Original file line number Diff line number Diff line change
Expand Up @@ -417,6 +417,7 @@ extern "C" {
#define BB_PLANE_AUDIT_NONE UINT32_C(0) /* [`ServeOut::audit`]: no audit row. */
#define BB_PLANE_AUDIT_APPLIED UINT32_C(1) /* [`ServeOut::audit`]: the request applied; the row's outcome is `applied`. */
#define BB_PLANE_AUDIT_REJECTED UINT32_C(2) /* [`ServeOut::audit`]: the request was rejected after it was judged; the row's outcome is */
#define BB_PLANE_AUDIT_DEGRADED UINT32_C(3) /* A [`RECORD_AUDIT`] write's outcome only (never [`ServeOut::audit`]): the unit was served with */
#define BB_PLANE_CHAIN_LENGTH_PREFIXED UINT32_C(1) /* [`RecordChain::framing`]: each field of the record's digest is length-prefixed. */
#define BB_PLANE_CHAIN_PIPE_SEPARATED UINT32_C(2) /* [`RecordChain::framing`]: the fields of the record's digest are joined by `|`. */
#define BB_PLANE_CHAIN_DIGESTS_SCOPE UINT32_C(1) /* [`RecordChain::flags`]: the record's scope enters its digest. */
Expand Down
2 changes: 1 addition & 1 deletion crates/busbar-contract/src/abi/plane/check.rs
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,7 @@ fn records(buf: &[RecordWrite], n: u64, arena: u64, b: &Bounds) -> Result<(), Fa
code(
u64::from(r.kind),
u64::from(super::AUDIT_APPLIED),
u64::from(super::AUDIT_REJECTED),
u64::from(super::AUDIT_DEGRADED),
"record.audit_outcome",
)?;
if r.key.len == 0 {
Expand Down
4 changes: 4 additions & 0 deletions crates/busbar-contract/src/abi/plane/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -591,6 +591,10 @@ pub const AUDIT_APPLIED: u32 = 1;
/// [`ServeOut::audit`]: the request was rejected after it was judged; the row's outcome is
/// `rejected`.
pub const AUDIT_REJECTED: u32 = 2;
/// A [`RECORD_AUDIT`] write's outcome only (never [`ServeOut::audit`]): the unit was served with
/// something the caller asked for left out (a control the far end's form cannot carry); the row's
/// outcome is `degraded`, the 1.5.5 row's.
pub const AUDIT_DEGRADED: u32 = 3;

/// [`RecordChain::framing`]: each field of the record's digest is length-prefixed.
pub const CHAIN_LENGTH_PREFIXED: u32 = 1;
Expand Down
4 changes: 2 additions & 2 deletions crates/busbar-contract/src/abi/tests/plane_check_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -700,15 +700,15 @@ fn an_audit_record_names_its_outcome_and_action() {
record_kinds: 0,
..bounds()
};
for outcome in [AUDIT_APPLIED, AUDIT_REJECTED] {
for outcome in [AUDIT_APPLIED, AUDIT_REJECTED, AUDIT_DEGRADED] {
r.kind = outcome;
assert_eq!(
check_on_piece(Ready, &o, (&[], &[r], &[]), &caps(), &none),
Ok(()),
"outcome {outcome}"
);
}
for outcome in [AUDIT_NONE, AUDIT_REJECTED + 1, u32::MAX] {
for outcome in [AUDIT_NONE, AUDIT_DEGRADED + 1, u32::MAX] {
r.kind = outcome;
assert_eq!(
piece(&o, &[], &[r], &[]),
Expand Down
3 changes: 3 additions & 0 deletions crates/busbar-contract/src/plane_calls.rs
Original file line number Diff line number Diff line change
Expand Up @@ -270,6 +270,9 @@ pub struct PlaneRegistration {
pub trust_keys: Vec<crate::plane::TrustKeyDecl>,
/// The tail's sentence refusing a forwarded caller credential; `None` = it states none.
pub caller_credential_refusal: Option<&'static str>,
/// Whether the tail states `TAIL_FALLBACK`: the plane is the catch-all every unclaimed path
/// falls through to, and its card is the flat one (at most one registered plane).
pub fallback: bool,
/// The door's own `validate` over a whole section (its settings, JSON): `Ok`, or the door's
/// words. The kernel runs it where the section is parsed and where an admin write lands.
pub validate: SectionJudge,
Expand Down
2 changes: 1 addition & 1 deletion crates/busbar-kernel-egress/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ pub use pool::{
Failover, Member, OnExhausted, Pool, DEFAULT_FAILOVER_CAP, DEFAULT_FAILOVER_DEADLINE_SECS,
};
pub use select::{RequestCtx, WeightedFloor};
pub use walk::{Step, Taken, Walk, WalkPorts};
pub use walk::{Shape, Step, Taken, Walk, WalkPorts};
pub use wire::Shed;

#[cfg(test)]
Expand Down
12 changes: 12 additions & 0 deletions crates/busbar-kernel-egress/src/ports.rs
Original file line number Diff line number Diff line change
Expand Up @@ -383,6 +383,14 @@ pub trait Clock: Send + Sync {
/// seconds, and a budget close to a second boundary would collapse to zero.
fn now_millis(&self) -> u128;

/// Microseconds since the same fixed point, for a latency sample: 1.5.5 measured an
/// attempt's latency in fractional milliseconds, so a sub-millisecond answer still records
/// (an integer `0` is the EWMA's "no sample"). A clock without the precision answers its
/// milliseconds scaled.
fn now_micros(&self) -> u128 {
self.now_millis().saturating_mul(1000)
}

/// A future that completes no earlier than `ms` milliseconds from now.
fn sleep(&self, ms: u64) -> BoxFut<'_, ()>;
}
Expand All @@ -395,6 +403,10 @@ pub trait Telemetry: Send + Sync {
/// One upstream attempt was started against this member.
fn upstream_attempt(&self, pool: &str, destination: DestinationId);

/// A served attempt's time to the upstream's response head, in milliseconds (the destination's
/// latency signal, a bounded proxy that never waits out a streamed body).
fn upstream_latency(&self, _destination: DestinationId, _ms: f64) {}

/// One attempt failed, with the disposition label the previous release used.
fn upstream_failure(&self, pool: &str, destination: DestinationId, disposition: &'static str);

Expand Down
99 changes: 85 additions & 14 deletions crates/busbar-kernel-egress/src/walk.rs
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,21 @@ pub struct WalkPorts<'p> {
pub pools: &'p HashMap<String, Pool>,
}

/// THE SHAPE A UNIT'S HOOKS PUT ON ITS PICKS (the design's route pump, "Hooks": the routing-stage policy
/// keeps and orders the routed pool's members; a required restrict holds a pool the walk spills
/// into): each pick's admissible members, the ones kept, and the order the walk prefers among them
/// (empty = the weighted floor's own). `None` = a required restriction no member satisfies: the
/// walk answers [`Shed::restrict_no_lane`] from there.
pub trait Shape {
/// `members` of a pick, as the unit's hooks leave them: the walk's own pool (`primary`) or a
/// pool it spills into.
fn shape(
&self,
members: Vec<Member>,
primary: bool,
) -> Option<(Vec<Member>, Vec<DestinationId>)>;
}

/// The walk's whole budget over `pool`, seconds: the pool's request timeout, `0` for a pool that is
/// not configured.
#[must_use]
Expand Down Expand Up @@ -184,6 +199,17 @@ impl Walk {
&self.ctx
}

/// The pool the walk is in and whether it is the walk's own (`true`) rather than a spill;
/// `None` once every path is spent.
#[must_use]
pub fn walking(&self) -> Option<(&str, bool)> {
match &self.phase {
Phase::Primary(name) => Some((name, true)),
Phase::Spill(name) | Phase::Terminal(name) => Some((name, false)),
Phase::Shed(_) => None,
}
}

/// The walk ends here, before its pool's terminal: every step from now answers `shed`.
pub fn refuse(&mut self, shed: Shed) {
self.phase = Phase::Shed(shed);
Expand All @@ -203,6 +229,17 @@ impl Walk {
ports: &WalkPorts<'_>,
affinity: Option<u64>,
token: &Pass<Route>,
) -> Step {
self.next_shaped(ports, affinity, None, token)
}

/// [`Self::next`], each pick's members as the unit's hooks `shape` them.
pub fn next_shaped(
&mut self,
ports: &WalkPorts<'_>,
affinity: Option<u64>,
shape: Option<&dyn Shape>,
token: &Pass<Route>,
) -> Step {
loop {
if self.ctx.expired(ports.clock.now_secs()) {
Expand All @@ -218,9 +255,13 @@ impl Walk {
return Step::Shed(Shed::empty_pool());
}
if self.hops <= pool.failover.max_hops {
if let Some(taken) = self.pick(ports, pool, affinity, token, true) {
self.hops += 1;
return Step::Take(taken);
match self.pick(ports, pool, affinity, shape, token, true) {
Ok(Some(taken)) => {
self.hops += 1;
return Step::Take(taken);
}
Ok(None) => {}
Err(shed) => return Step::Shed(shed),
}
}
self.phase = Phase::Terminal(name);
Expand All @@ -229,8 +270,10 @@ impl Walk {
let Some(pool) = ports.pools.get(&name) else {
return Step::Shed(pool_shed(ports, &name, token));
};
if let Some(taken) = self.pick(ports, pool, None, token, false) {
return Step::Take(taken);
match self.pick(ports, pool, None, shape, token, false) {
Ok(Some(taken)) => return Step::Take(taken),
Ok(None) => {}
Err(shed) => return Step::Shed(shed),
}
self.phase = Phase::Terminal(name);
}
Expand Down Expand Up @@ -285,36 +328,64 @@ impl Walk {

/// THE ONE PICK, over `pool`'s members this unit has not tried: the walk's own pool
/// (`primary`, with the unit's affinity) and every pool it spills into (degraded).
///
/// # Errors
///
/// The unit's hooks hold the pool to a restriction no member satisfies: that shed, which every
/// step from here answers.
fn pick(
&mut self,
ports: &WalkPorts<'_>,
pool: &Pool,
affinity: Option<u64>,
shape: Option<&dyn Shape>,
token: &Pass<Route>,
primary: bool,
) -> Option<Taken> {
let members = pool.admissible_members();
) -> Result<Option<Taken>, Shed> {
let admissible = pool.admissible_members().into_owned();
let (members, order) = match shape {
Some(shape) => match shape.shape(admissible, primary) {
Some(shaped) => shaped,
None => {
let shed = Shed::restrict_no_lane();
self.phase = Phase::Shed(shed.clone());
return Err(shed);
}
},
None => (admissible, Vec::new()),
};
let now = ports.clock.now_secs();
let mut picked = pick_among(
let Some(mut picked) = pick_among(
&PickInput {
breaker: ports.breaker,
capacity: ports.capacity,
floor: ports.floor,
pool: &pool.name,
members: &members,
affinity,
preference: None,
preference: (!order.is_empty()).then_some(order.as_slice()),
now,
token,
},
&mut self.ctx,
)?;
let member = members
) else {
return Ok(None);
};
let Some(member) = members
.iter()
.find(|m| m.destination == picked.destination)?
.clone();
.find(|m| m.destination == picked.destination)
.cloned()
else {
return Ok(None);
};
let probe = picked.take_probe_epoch();
Some(self.take(&pool.name, member, picked.permit, probe, !primary))
Ok(Some(self.take(
&pool.name,
member,
picked.permit,
probe,
!primary,
)))
}

/// Take `member` of `pool` for the next attempt: excluded from every pick of the unit after it.
Expand Down
25 changes: 25 additions & 0 deletions crates/busbar-kernel/src/appbuild.rs
Original file line number Diff line number Diff line change
Expand Up @@ -540,6 +540,19 @@ impl InstalledLimits {
}
}

/// WHAT THE COMPOSITION ROOT KEEPS OF A RESOLVED CONFIGURATION beside the generation built from it
/// (spec Part 1 line 569: a door plane is handed one validated `{section: value}` object per
/// `open`/`refresh`): the root projects the sections, providers and pool bounds its door planes are
/// sealed over, and reads the projection back when the generation is swapped in.
pub type ConfigProjection = fn(&config::RootCfg) -> std::sync::Arc<dyn std::any::Any + Send + Sync>;

static CONFIG_PROJECTION: std::sync::OnceLock<ConfigProjection> = std::sync::OnceLock::new();

/// Bind the composition root's [`ConfigProjection`], once, before the first build.
pub fn set_config_projection(project: ConfigProjection) {
let _ = CONFIG_PROJECTION.set(project);
}

#[cold] // boot/admin-only — keeps hot text dense (never inlined into a warm path)
#[inline(never)]
pub fn build_app_from_config(
Expand All @@ -551,6 +564,8 @@ pub fn build_app_from_config(
config_paths: (Option<std::path::PathBuf>, Option<std::path::PathBuf>),
prior: Option<&state::App>,
) -> Result<(state::App, Option<GovCredentialRotation>, InstalledLimits), String> {
// The root's projection of this configuration, taken before any part of it is consumed.
let config_projection = CONFIG_PROJECTION.get().map(|project| project(&cfg));
// Install the resolved operational limits process-wide BEFORE any subsystem reads them —
// running here (not in main) so a config APPLY/RELOAD refreshes them too. The values threaded
// explicitly (client/store/router/TLS) read `cfg.limits` directly; the deep call-stack sites
Expand Down Expand Up @@ -1644,6 +1659,14 @@ pub fn build_app_from_config(

// Populate the NEUTRAL carrier field-by-field from the already-resolved config (pre-resolved secret
// plaintexts + rate-card-derived costs + resolved context/tokens are in `lane_inputs`/`pool_inputs`).
// THE KERNEL'S OWN TABLES over the same resolved sections, for the read seam when no plane
// contributes a runtime of its own.
let config_tables = Arc::new(busbar_kernel::plane_host::ConfigTables::of(
&lane_inputs,
&pool_inputs,
&by_model,
cfg.upstream_credentials,
));
let fallback_build_input = PlaneBuildInput {
lanes: lane_inputs,
pools: pool_inputs,
Expand Down Expand Up @@ -1757,6 +1780,7 @@ pub fn build_app_from_config(
// read on the hook seam with a single relaxed load.

let app = App {
config_projection,
plane_sections: Some(cfg.plane_sections.clone()),
// Telemetry-bank slot table for this generation (built above as a local, BEFORE the
// config-derived collections moved into the fallback plane's runtime bundle so its
Expand All @@ -1768,6 +1792,7 @@ pub fn build_app_from_config(
// seam; the snapshot names only the `&'static str` key, and `App::llm_runtime` downcasts the
// slot on the money path. Absent slot (featureless build) reads the empty default.
fallback_runtime_key,
config_tables,
store,
// The container planes' breaker cells: PROCESS-LIFETIME, reused across an apply/reload the
// way the HTTP client pool and governance state are — a config swap must not un-trip a
Expand Down
9 changes: 9 additions & 0 deletions crates/busbar-kernel/src/core_routes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -191,6 +191,15 @@ impl CoreRouter {
self
}

/// The methods a core route is already mounted under at exactly `path`.
pub(crate) fn methods_at(&self, path: &str) -> Vec<RouteMethod> {
self.table
.by_path
.get(path)
.map(|rows| rows.iter().map(|(m, _)| *m).collect())
.unwrap_or_default()
}

/// Split into the mounted router and the table describing it.
pub(crate) fn into_parts(self) -> (Router<Arc<AppHandle>>, CoreRouteTable) {
(self.router, self.table)
Expand Down
Loading
Loading