← Ledger

0011 — KILN federation seam: Rocky as KILN-aware consumer

Date: 2026-05-10 Status: ratified — owner: alex@devarno.com (2026-05-10). This ADR formalises only the seam contract (the four pass-through guarantees that already hold). Phase numbering, KAHN-owner review, and the federation transport itself are intentionally deferred to a future plan kickoff. Supersedes: none — first KILN federation declaration for rocky-hq Superseded-by: none — current

Context

Three independent artefacts converged this week and forced the question of what "KILN federation" means inside rocky-hq:

  1. KAHN side: KILN spec is real and phased. kahn-hq:docs/KAHNxKILN.md (DRAFT, 2026-04-24, Null0) defines KILN as KAHN's adaptive-feedback layer — convergence scoring, score-plateau early termination, diagnostic preamble. Phase 0 (diagnostic feedback) and Phase 1 (convergence_score = passed_checks / total_checks) are the high-leverage near-term work; Phase 2 (early termination on plateau) and Phase 3 (bandit scheduling) are deferred. KILN lives in KAHN; Rocky is downstream of it.

  2. Rocky side: forward-compatibility seam already exists. console/CLAUDE.md SS-07 documents that convergence_score and early_stop_reason are optional KAHN fields, that UI components render no-op slots when absent, and that we never gate features on KILN-presence. docs/specs/2026-05-04-rocky-phase-3e.md D7 ratifies the aggregator fold rule: pass-rate is computed from Outcome regardless of KILN, KILN-fields are summed/averaged only over runs that carry them, and both KILN-on and KILN-off event shapes must produce a valid RalphRunsAgg24h. @rocky-hq/contracts@0.1.0 (Phase 4) ships these as .optional() zod fields with no consumer-side codegen — additive bumps don't break older consumers (D6 of Phase 4).

  3. Operator pressure: 0/0/0 dashboards. The dash/ralph-runs panel reads zero today. Two distinct causes were diagnosed in the bringup session that motivated this ADR (see also console PR #13): no run had ever been submitted end-to-end (wire-format mismatch between @rocky-hq/contracts SubmitRunOpts and ralph serve's SubmitRunRequest); and the federation question — whose runs the dashboard is supposed to surface — has never been written down.

The conceptual collision flagged in docs/decisions/2026-05-02-rename-fleet-to-hearth.md ("KAHN's RALPH" ≠ "Rocky's RALPH"; same name, adjacent problems, different architectures; "premature unification would be over-engineering") still stands. KILN federation is not a unification of those two RALPHs — it is a contract for how KILN signals flow across them when both are operating in the same operator's environment.

This ADR draws the federation seam in one direction so downstream phase planning has something concrete to point at. It deliberately does not propose a new service, a new deployment, or a new schema bump.

Decision

Rocky-hq's role in KILN federation is consumer, not orchestrator. Rocky-hq's RALPH (SS-07, sequential prompt queue) and KAHN's RALPH (DAG iterative refinement loop) remain architecturally distinct per ADR 2026-05-02-rename-fleet-to-hearth. KILN is KAHN's signal model. Rocky federates with KILN by:

What Rocky guarantees (consumer side)

  1. Pass-through, never compute. Rocky never originates convergence_score or early_stop_reason. Either the upstream KAHN/RALPH attempt populates them or they remain undefined. Rocky's kahn-emit path (SS-07, Phase 3b) preserves these fields verbatim.
  2. No-op when absent. Every Rocky surface that renders a KILN-derived signal — currently dash/ralph-runs and the KILN-fields aggregator (RalphRunsAgg24h, Phase 3e D7) — must remain valid and render a documented "no KILN data" state when the signal isn't present. Existing tests already enforce this; the fold rule in Phase 3e D7 is now load-bearing for the federation contract.
  3. Single fold rule, owned here. The KAHN Outcome → pass/fail fold (Phase 3e D7: clean/clean_with_flake → pass; partial/stuck/catastrophic → fail) is the Rocky-side fold. Other consumers may fold differently; Rocky doesn't second-guess KAHN's Outcome, only re-bins it for human-facing pass-rate math.
  4. Schema versioning by contracts. KILN field shape changes go through @rocky-hq/contracts. Additive (new optional field) is non-breaking by D6 of Phase 4. Removing or repurposing an existing KILN field is a contract major-bump and must supersede this ADR.

What Rocky does not guarantee, and explicitly defers

  1. Federation across multiple emitters is out of scope here. The current SS-04 runs aggregator (console/src/lib/workspace/ralph-runs/, Phase 3e) reads from a single ralph serve source per workspace. Cross-workspace federation — pulling KILN signals from kahn-hq runs alongside Rocky's own runs, presenting them in one dashboard — is a separate phase. Phase numbering is intentionally not reserved here; it will be assigned at plan kickoff, after Phases 5 (HEARTH LocalDocker), 6 (HEARTH Kustomize/DevarnoCloud), and 7 (Polar entitlements) close.
  2. No KILN producer in Rocky. Rocky-hq does not implement Phase 0 (diagnostic preamble), Phase 1 (compute convergence_score), or Phase 2 (early-stop) from kahn-hq:docs/KAHNxKILN.md. Those belong to KAHN's orchestrator. If a Rocky-side analogue is ever wanted, it gets its own ADR; this one does not authorise it.
  3. No new schema in this ADR. No new event types. No new fields beyond what @rocky-hq/contracts@0.1.0 already ships. The federation seam is the existing optional-fields surface; this ADR formalises its semantics rather than expanding it.

What this ADR therefore authorises

  1. The console dash/ralph-runs panel (and any sibling panels the federation phase introduces) may render KILN-derived columns/badges when present, must hide or no-op them when absent, and must not crash on partially-populated runs. Existing tests in console/src/app/dashboards/dash%2Fralph-runs/page.test.tsx and the aggregator unit suite enforce both shapes — those tests are now load-bearing for the federation contract.
  2. The producer side of the seam (@rocky-hq/contracts/ralphKahnEvent, NodeAttempt, optional KILN fields) is frozen for Phase 5: no contract bumps for KILN reasons until the future federation plan opens with its own ADR. The Phase 5 HEARTH contracts bump (@rocky-hq/contracts@0.2.0, MILESTONES.md sub-phase 5b) is unrelated to KILN and proceeds.
  3. A KILN-federation spec and plan are reserved but unwritten (filenames + phase number assigned at plan kickoff). Open questions captured below; this ADR is the placeholder that prevents that future plan from being defined contradictorily.

Open questions (deferred to the federation plan, not blocking this ADR)

Acceptance (at ratification 2026-05-10)

This ADR ratifies only the seam contract — the four pass-through guarantees that already hold in console/src/lib/ralph/ and the Phase 3e aggregator. It does not reserve a phase number, schedule federation work, commit to a transport, or amend MILESTONES.md. Those come when the federation plan is opened.

Deferred to the federation plan kickoff:

  1. KAHN owner (Null0) review of consumer-side guarantees against kahn-hq:docs/KAHNxKILN.md Phase 0/1.
  2. Audit of the current kahn-emit path (console/src/lib/ralph/kahn-emit.ts + aggregator) against guarantees 1–4; file divergences as issues.
  3. Phase number assignment + MILESTONES.md update.

Sources