Skip to content

busbar-contract: YAML readers behind a yaml feature, enabled by busbar-kernel - #897

Closed
MattJackson wants to merge 20 commits into
predevfrom
lane-contract-yaml-feature
Closed

MattJackson wants to merge 20 commits into
predevfrom
lane-contract-yaml-feature

Conversation

@MattJackson

Copy link
Copy Markdown
Collaborator

Stacked on #888, which carries #838. This branch contains #888's head, 8ece3a2. That base already has the in-tree busbar-plane-mcp crate removed, so there is no modify/delete conflict. This PR's own change is the one commit on top, f995796. Once #888 lands, the diff shrinks to that commit.

Why. Today every plugin built against busbar-contract links serde_yaml_ng -> unsafe-libyaml (RUSTSEC-2024-0449). That includes stores, secrets, auth, hooks, exports and transports. Only two contract items read YAML:

  • section::split_section, the plane section-map split
  • plane_calls::dialect_facts, the door plane's open-time provider list

Only the host and planes call them.

What.

  • crates/busbar-contract/Cargo.toml: serde_yaml is optional, behind a new feature yaml = ["dep:serde_yaml"], off by default. The test-only serde_yaml dev-dependency is unchanged.
  • split_section, dialect_facts and the serde::Deserialize import that only split_section uses are now #[cfg(feature = "yaml")]. The module doc no longer intra-links the gated fn.
  • crates/busbar-kernel/Cargo.toml: one line, the busbar-contract edge gets features = ["yaml"].
  • busbar-a2a and the busbar root call the readers. They reach the feature through their own busbar-kernel edge (feature unification), so neither changes. No other workspace crate names either fn: I checked with git grep. The in-tree planes do not call them.

The template side is in busbar-release (into dev). Plane repos turn the feature on and keep the advisory ignore. Non-plane repos at a feature pin get a cargo-deny ban on serde_yaml_ng.

Not $. No behaviour change: same functions, same callers.

…p, pulled at a pinned rev; every gate reads the pinned planes as its base layer (P5, rows 106/107)

- crates/busbar-plane-mcp is deleted. GetBusbar/busbar-plane-mcp holds it, history imported with
  filter-repo; its logic crate is predev 00555bd's crate and its -plugin cdylib runs busbar's
  published conformance suite. The root pins it as one git row; the root's two edges take the
  workspace row; deny.toml allows the repo; plugins.yaml drops pending_crate and checks busbar out
  (its tests read the battery and qa/method-inventory.json at the pin).
- THE BASE LAYER (ARCHITECT row 106 (A)): Ctx gains a base beneath the overlay and above the disk.
  Ctx::workspace lays every pinned package of the plane kind at crates/<package>, read from the
  checkout cargo metadata resolves for the rev Cargo.lock pins (kind_isolation::plane_base), never
  written into the tree. with_overlay keeps it, so a plant still wins. Generic over the kind, no
  plane named. Fails closed: a pinned plane cargo cannot resolve is an Err naming it and its rev.
  kind-isolation's own mount is unchanged. No ledger row moves.
- RED arms: xtask/tests/pinned_planes_base.rs (the base is laid from the checkout and nothing of it
  is on disk; a plant wins over it; structure-lint, config-schema, no-float-money, plane-purity and
  reachability each lose a passing row without it); declared_classes reads the pinned planes and
  none without the base.
- The tests that read the filesystem resolve a pinned plane through the same rule
  (crates/busbar/tests/common/pinned_planes.rs): capability-equality's proven mcp-server cells and
  its five-plane floor (with a RED arm that the evidence is not on disk and is read from the
  checkout); the kernel trust and core-admin plane-key ratchets take the pinned planes' keys;
  proto-deletion-gate.sh reads the door crate from its checkout.
- plugin-ci.yml: a plane repo runs plane-purity, structure-lint and config-schema at its busbar pin
  over its own change (scripts/fleet/plane-gates.sh, BUSBAR_PLANE_SOURCE): no row that passes over
  busbar's pinned plane may fail over the change.
… take the pinned planes too (tests/common/pinned.rs, fail-closed), and the sibling set is every plane the roster registers, with its five-plane floor (ARCHITECT row 106 (A))
…a door home; the plane step is an xtask plugin-gate; the pin moves to the merged plugin head

- Ctx::exists and Ctx::is_dir answer a directory the base layer lays (a pinned plane's crate and
  every directory in it), and Ctx::base_children lists what it lays under a directory: qa-names,
  plane-purity:roots, plane-pricing-blindness and structure-lint's scope rows read the pinned plane
  where it lived. construction's glob_dirs lists the laid crate beside the disk's, so the census's
  plane glob still matches its five crates.
- workspace-deps: a manifest the base lays is a pinned git dependency, never a crate on disk.
- PlaneRoots::over(cx): a door crate the base lays is its plane's door home (settings-leak,
  response-header, blocking-ffi).
- plugin-ci's plane step is `xtask plugin-gates plane` (the busbar gates over busbar's pinned plane
  and over the change, a row that stops passing is a finding), with selftest cases; the shell
  script is gone (script-allowlist: product checks are cargo xtask).
- busbar-plane-mcp pinned at a5e2ae355c, the head GetBusbar/busbar-plane-mcp#10 merged.
…oml keeps predev's store-memory row (no fixture-store: the kernel links an in-crate store double) beside this lane's busbar-plane-mcp pin
…s; the root pins it (/status rows 106/107)

BUSBAR-1.6.0.md l.2220 (#39): "plugin SOURCE never re-enters busbar". l.3962: extract each
plugin crate to its repo, pinned back as a git dependency in the root manifest's linked rows.
This takes the same shape as #838 for mcp and stacks on its base layer (ARCHITECT row 106 (A)).
Crates go 23 -> 22.

- crates/busbar-plane-decisions is deleted. GetBusbar/busbar-plane-decisions#13 carries predev
  5c99bef's crate byte for byte, with tests/conformance.{rs,json} in its -plugin twin, at
  busbar pin 5c99bef. The root pins that PR's head d78c070da4 with one git row. The
  `plane-decisions` edge in crates/busbar takes the workspace row.
- deny.toml allow-git gains the repo. plugins.yaml drops pending_crate. The decisions tests read
  none of busbar's files, so it needs no busbar_checkout.
- Cargo.lock: busbar-plane-decisions resolves from git. busbar-contract stays patched to the path
  crate, and the plugin-loader dev edge leaves with tests/conformance.rs.
- Every gate, test and script that reads crates/busbar-plane-decisions reads it through #838's
  base layer and pinned_planes resolver: Ctx::workspace lays every pinned plane at
  crates/<package> from its checkout, and nothing in it names a plane. So no reference in xtask,
  the tests or the ledgers changes. Ledgers: none touched (#838's ruling condition 6). The
  pinned plane is measured at the path it had, from the same bytes.
- .ci/default.yaml already builds the pinned busbar-plane-decisions-plugin cdylib ("plugin
  busbar-plane-decisions busbar-plane-decisions-plugin optional").
…-kernel turns it on

section::split_section and plane_calls::dialect_facts are the only contract items that name
serde_yaml (the serde_yaml_ng rename). serde_yaml is now optional behind `yaml = ["dep:serde_yaml"]`,
off by default. busbar-kernel's busbar-contract edge enables it. busbar-a2a and the busbar root call
the readers too and reach the feature through their busbar-kernel edge (feature unification).

A plugin of a non-plane kind built against the contract no longer links serde_yaml_ng ->
unsafe-libyaml, so it carries no RUSTSEC-2024-0449. The test-only serde_yaml dev-dependency
is unchanged.
@MattJackson
MattJackson marked this pull request as draft October 14, 2026 01:01
@MattJackson
MattJackson marked this pull request as ready for review October 14, 2026 01:01
… pinned-plane helper by reference (root is a PathBuf; E0308 at :1233)
…ut (dirs_for_globs filters with Ctx::is_dir, disk then base layer); RED: a plane present only in the base layer is counted
…dirs_for_globs counts a pinned plane from the base layer) into lane-p5-extract-plane-decisions
…er the scan roots (a pinned plane's crate), so rules that read lines read a pinned plane; RED: forbid-unsafe finds the attribute in a base-laid plane's lib and reports its absence MISSING
… scan carries pinned-plane sources; forbid-unsafe MISSING fix) into lane-p5-extract-plane-decisions
…s tools type leaves the secret inventory, and the architecture page names only paths on disk

- kind_isolation: plane_kind_src_roots unions the root manifest's pinned plane rows
  (pinned::pinned_plane_dirs), so a context without the base lists the pinned plane's root and
  plane-purity:roots refuses it by name; plane_kind_crates refuses a pinned plane the census
  cannot read, so reachability:plane-crates is red without the base (pinned_planes_base's two
  RED arms).
- secret_refs: TokenExchangeCfg left the tree with the plane; its references are read at the
  door's declared paths through the DoorSection row, so the stale inventory entry is removed.
- docs/architecture.md: the in-tree plane directories, and the MCP plane's own repository.
… and is pinned; the page names only the in-tree plane directories
@MattJackson

Copy link
Copy Markdown
Collaborator Author

Superseded by ruling: a contract feature breaks #38(b) feature-invariance, and moving split_section forces a plane-dup copy. The contract keeps serde_yaml unconditionally, as on predev, and the RUSTSEC-2024-0449 ignore stays with its reason.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant