Deployment shapes: machine-as-brain vs mesh-brain lobe profiles — spec + plan (0.41.1)#113
Conversation
…esh-brain (devague /think) Deployment shape becomes a first-class, safely-selectable axis orthogonal to the #108 hardware profiles: machine-as-brain (default, one box hosts every lobe it can) vs per-box mesh-brain lobe profiles (spark-lobe drops Gemma senses; thor-lobe drops the Qwen cortex). Cross-box story: per-box honesty only; one-lobe-per-box end-state tracked as #112. Grounded by the #109 verification (closed): fp8-KV is an sm_110-conditional trait and the attention-backend env is dead on the shared pinned nightly. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01U9ybFURhQxT9UpCgQNVL67
t1 shape schema -> (t2 budgets | t3 render+goldens | t5 dropped-lobe honesty) -> t4 init --shape -> (t6 GB10 validation | t7 Thor validation) -> t8 docs. Version 0.40.4 (every-PR-bumps rule). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01U9ybFURhQxT9UpCgQNVL67
|
/agentic_review |
PR Summary by QodoAdd deployment-shapes spec + implementation plan (0.40.4)
AI Description
Diagram
High-Level Assessment
Files changed (8)
|
…spec/brain-shapes Resolves the every-PR-bump collision on CHANGELOG.md / pyproject.toml / uv.lock by taking main's side (0.41.0); the branch's own 0.40.4 bump is dropped and re-applied on top as 0.41.1. #110 landed the #108 profile substrate this spec+plan composes on. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01U9ybFURhQxT9UpCgQNVL67
…erged base) Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01U9ybFURhQxT9UpCgQNVL67
#110 merged mid-flight (the #108 implementation, 0.41.0), so the frame and plan are re-cut against what actually shipped: the dropped-lobe contract is now flag-not-omit (capabilities feasible:false, /v1/models omits, generate lane 404 role_infeasible — c11/h3 rejected, c17/h13 recaptured and covered by t5); shapes own all six Colleague roles per user decision (stt/tts are first-class shape members over the audio overlay — c18, t1); shape data files are TOML matching lobes/profiles/builtin/; t1/t3/t5 instructions now name the landed modules instead of 'when it lands'. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01U9ybFURhQxT9UpCgQNVL67
|
…nses (#113) With the co-resident heavy lobe gone, the remaining heavy lobe gets its FULL native budget in this PR rather than deferred to #112: - spark-lobe [overrides.cortex]: gpu_mem_util 0.44 -> 0.60 (the proven GB10 primary value, not the co-resident reclaim-sum), max_model_len 131072 (no override, i.e. co-resident) -> 262144 (the checkpoint's native 256K). - thor-lobe [overrides.senses]: gpu_mem_util stays 0.44, max_model_len 32768 (co-resident) -> 131072 (the Gemma checkpoint's native 128K). tests/test_shape_budgets.py assertions updated first (TDD) to demand the new values; goldens regenerated via tests/goldens/regen.py -- only the shapes/ goldens affected by these two overrides changed (thor-lobe__base.env and the four flat profile goldens are byte-identical, since senses is infeasible on the base card and the card baselines are untouched). Known follow-up: tests/test_init_shape.py hardcodes spark-lobe PRIMARY_GPU_MEM_UTIL as "0.44" in three places (lines 132, 166, 228) and now fails post-rise to 0.60 -- out of this task's owned-files scope (any Python source besides tests/test_shape_budgets.py), left for a follow-up.
Live validation caught the gap: `lobes init --shape spark-lobe --apply` rendered MULTIMODAL_FEASIBLE=false honestly, but the base compose kept all four core services unconditional, so `lobes fleet up` still booted the dropped senses lobe (observed: model-gear-vllm-multimodal Started) and ate the exact GPU budget the shape reclaimed. A dropped lobe must not RUN, not merely be flagged. Fix — a GENERATED compose override, mirroring the audio-overlay pattern: - `lobes init --shape <mesh-shape> --apply` now writes docker-compose.shape.yml (only when the shape drops >=1 core role) that parks each dropped core service in the inert `shape-dropped` compose profile (nothing activates it, so `docker compose up` skips it) and clears the gateway's depends_on with the compose `!reset` tag (removes the dangling edge to the profile-disabled service; the remaining default gears start regardless of ordering, which the gateway tolerates). Content is derived from the t3 render API (shape_render.ROLE_SERVICE over schema.ROLES), not hardcoded per shape. machine-as-brain / bare init write nothing (byte-identical scaffold); re-init to machine-as-brain scrubs a stale override; dry-run reports write/remove. - _compose.py gains SHAPE_OVERLAY, shape_overlay_present(), shape_dropped_containers() (reads the override file — stdlib line scan, no YAML dep) ; _compose_files() appends `-f docker-compose.shape.yml` LAST (after audio, so its !reset lands last); fleet_containers() excludes the dropped gear. Note: docs confirm `!reset` CLEARS a value (list *replacement* is `!override`); clearing the gateway depends_on is the correct fix here. Requires Docker Compose v2.24+ (compose-spec merge tags). 21 new tests; full suite green. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_012Cg9tcyAAC5CmDXuQXDvTU
…ntract matrix, live evidence + docs (#112) (0.43.0) (#121) * feat(t3): honest referral — opt-in peer config annotates capabilities + role_infeasible 404s Mesh-brain t3 (issue #112, the confirmed cross-box decision: direct + referral). A box that dropped a role can now name the peer that hosts it: - Peer-config surface: one OPERATOR-DECLARED env var per core role's backend — PRIMARY/MULTIMODAL/EMBED/RERANK_PEER_ORIGIN (PEER_ORIGIN_ENV in lobes/gateway/_config.py), mirroring the *_FEASIBLE idiom. Full origins only, never derived from hostnames/interfaces (the #92 lesson). - With peers declared, GET /capabilities / lobes capabilities (gateway and offline paths) add hosted_by to each unhosted (feasible:false) role, and the 404 role_infeasible body carries the same referral; /v1/models is untouched. - Zero peer config = byte-identical responses to the pre-referral contract (regression-pinned against the exact pre-change bytes). - NO data-plane proxying: the referral is an annotation for the caller to dial directly — the gateway never opens an outbound connection for an unhosted-role request (test-enforced at the handle_post seam and over a real HTTP loopback with a hard no-outbound guard). Proxy-lobes stays deferred to issue #115. Plumbing: RoutingTable.peer_origins (default empty), the shared lobes.roles.annotate_peer_referrals helper (one implementation for both surfaces), gateway compose-template env passthrough + env.example docs, docs/deployment-shapes.md referral section, lobes explain shapes update, and the regenerated template-defaults golden. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_013ukvsit214BtGfiTRbdnQC * Add orin-small reference shape: declared-but-unvalidated small-model corner (t2, issue #112) The Jetson AGX Orin 64GB reference for the mesh-brain end-state: hosts NEITHER heavy generate lobe (cortex and senses both absent), keeps the opt-in `minor` gear (vllm-minor) + embedder + reranker + audio. `minor` is not one of the six first-class Colleague roles (SHAPE_ROLES), so the Shape schema's role vocabulary is extended minimally: a new COLLEAGUE_ROLES constant (the six roles machine-as-brain hosts) is split out from SHAPE_ROLES (COLLEAGUE_ROLES + the opt-in OPT_IN_ROLES = ("minor",)) so the identity-shape invariant stays correct now that SHAPE_ROLES is a strict superset. `minor` carries no Profile knobs of its own (like stt/tts) and maps to the already-shipped vllm-minor compose service — zero new compose files, zero core-role render-path branches. Ships as pure declared data per the #108 rule, mirrored exactly from base.toml's unrecognised-card fallback discipline: renders against the existing base/spark/thor card profiles (no new "orin" Profile), goldens only, no live validation claimed anywhere (deployment-shapes.md, the explain-catalog shapes topic, CLAUDE.md, and the --shape CLI help all mark it declared/unvalidated). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_013ukvsit214BtGfiTRbdnQC * test(t4): contract-test matrix for the reference shapes — per-(shape, dropped role) honesty cells, referral-aware 404s, t1 golden-value pins One data-driven enumeration of every (built-in shape, dropped core role) cell, derived from the shipped shape TOMLs' hosts lists so a future shape is covered automatically. Per cell: capabilities flag feasible:false on both the gateway payload and the CLI registry, /v1/models omits the role, every TIER_ROLE-derived alias 404s role_infeasible dialing nothing, and with peer origins declared the 404 + capabilities carry the RIGHT per-role hosted_by referral (orin-small's two drops prove referrals never cross). Includes a real-HTTP loopback per cell with an outbound tripwire, hosted- lane liveness per shape (incl. orin-small's minor gear), the honest unspecified-model 404 on orin-small, and the t1 full-native reclaim values (262144 / util>0.30 on spark-lobe; 131072 / util>0.14 on thor-lobe) pinned as explicit assertions against the golden files so a regen cannot silently lower them. No production code changed; machine-as-brain goldens untouched. Part of the mesh-brain end-state plan (issue #112), task t4. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_013ukvsit214BtGfiTRbdnQC * t5: mesh-brain acceptance — orin-small + referral phases in accept-shape.sh, live Thor referral evidence (#112 t5) accept-shape.sh gains the orin-small shape arm (dropped-role checks now loop over multiple dropped roles) and an opt-in phase 4b that verifies hosted_by referrals on both honesty surfaces whenever <PREFIX>_PEER_ORIGIN is declared. docs/evidence/2026-07-14-accept-referral-thor.txt: live on the physical Thor — referral 404s + capabilities hosted_by (real declared Spark origin), hosted lanes serving through the same gateway, cross-box cortex reachability, and byte-for-byte shape restore. Full-shape boots reuse the #113 transcripts per operator decision. * docs(t6): mesh-brain end-state — the four #112 decisions, tax table with ratios, live referral evidence (#112 t6) Writes the mesh-brain end-state section of docs/deployment-shapes.md, records all four #112 decisions (direct+referral, cheap-gear co-residence, the Spark/Thor/Orin reference shape assignment, and the mixable shape axis) quoting only measured numbers from the three committed acceptance transcripts, and aligns CLAUDE.md and lobes/explain/catalog.py with the same framing. Fixes a couple of stale cross-references in docs/machine-profiles.md and docs/colleague-stack.md (the "always-on duo" / "four co-resident backends" claims predate the shape axis) and the accept-shape.sh usage block (missing orin-small). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_013ukvsit214BtGfiTRbdnQC * chore: bump version to 0.43.0 + changelog for the #112 mesh-brain end-state implementation Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_013ukvsit214BtGfiTRbdnQC * evidence: thor-lobe applied for keeps on the physical Thor — full unattended PASS incl. referral phase (#112 t5) Live PR test: this box now serves Gemma senses (131072 @ util 0.30) and not Qwen — cortex feasible:false with hosted_by http://spark.tail0be7e0.ts.net:8001 on both surfaces and in the 404 body. Gateway runs the 0.43.0.dev239 TestPyPI build of this branch. The re-scaffold also picked up the #110 reranker knobs: rerank_relevance PASS (ordering [0,2,1], 1.45s) — resolving the stale-deployment hang recorded in 2026-07-14-accept-referral-thor.txt and #105/#119. First unattended attempt hit the documented unified-memory boot race (21.89 GiB free vs 36.85 needed; 16 restarts) — drop_caches freed 96 GiB and this second run passed end-to-end (fleet healthy in 282s). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_013ukvsit214BtGfiTRbdnQC * eidetic: record the Thor's permanent move to thor-lobe (Gemma-only, cortex referred to the Spark) (#112/#121) * chore: uv.lock 0.43.0 + agex pr events * fix: orin-small actually activates its minor lane — render COMPOSE_PROFILES + gateway wiring (Qodo find, #112 t2) Hosting an opt-in role now renders its activation env in shape_env (OPT_IN_ACTIVATION_ENV mirroring the template defaults, kept honest by a mirror test): COMPOSE_PROFILES=minor un-gates the profile-gated vllm-minor service and MINOR_BASE_URL/MINOR_SERVED_NAME wire the gateway backend. Verified end-to-end: a scaffolded orin-small's compose config now includes vllm-minor (was: gateway+pooling only, no generate lane). orin-small goldens +3 lines each; machine-as-brain/spark-lobe/thor-lobe goldens byte-identical. Also: accept-shape.sh validates its non-core CLI deps up front (curl, python3, docker, uv) per the review's skill insight. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_013ukvsit214BtGfiTRbdnQC --------- Co-authored-by: Claude Fable 5 <noreply@anthropic.com>



Spec + plan (devague
/think→/spec-to-plan, both frames converged and committed): deployment shape becomes a first-class, safely-selectable axis — orthogonal to the per-machine hardware profiles that landed in #110.The two shapes
lobes init, goldens byte-identical).Selection is flag-first:
lobes init --shape <machine-as-brain|spark-lobe|thor-lobe>, dry-run by default,--applyto commit (wizard parked as follow-up). Cross-box story for this change is per-box honesty only; gateway proxying and the brain-level view are deferred to the #112 end-state design.Aligned to the shipped #110 substrate (updated mid-flight)
#110 (the #108 implementation) merged while this PR was open; the branch is merged with main (0.41.0 → this PR bumps 0.41.1) and the spec/plan were re-cut against what actually shipped:
feasible:false(annotated),/v1/modelsomits it, and the generate lane returns 404role_infeasible— targeting the landed machinery (lobes/gateway/_config.pyFEASIBLE_ENV,_routing.py,server.py::_feasibility_response,roles.py), never a parallel path.lobes/profiles/schema.py/loader.py/render.py), the audio pair via the audio overlay.lobes/profiles/builtin/; per-(shape,card) goldens are additive to the shippedtests/goldens/*.env+regen.pyconvention.Evidence this stands on
VLLM_ATTENTION_BACKENDis dead on the GB10's pinned image too (undeclared invllm.envs; TRITON_ATTN comes from Gemma4 model-side forcing).profiles:stanza in the fleet template — today "Spark drops Gemma" means hand-editing the compose.The plan: 8 tasks, 5 waves
t1 shape schema → (t2 budget re-derivation | t3 render+goldens | t5 dropped-lobe honesty) → t4
init --shape→ (t6 GB10 validation | t7 Thor validation) → t8 docs+evidence. Wave-1 tasks are file-disjoint; every task carries TDD acceptance criteria and OWNS-scoped instructions. Remaining risks: t7 needs hands on the physical Thor; reclaim numbers are measured in t6, not specced.Related: #108/#110 (substrate, landed), #109 (closed by this verification), #112 (one-lobe-per-box end-state, filed as part of this work), #105/#106 (rerank ordering, expected-failure gate in t7).
Version: 0.41.1 (every-PR-bumps rule; merged with main's 0.41.0). Docs/spec/plan only — no source changes; 1419 tests pass,
agex pr lintclean.