Skip to content

eat-up.sh: deploy EAT release-1.1.0 on request, vLLM CPU v0.28.0 by digest, 1.1.0 config checks, H1c pre-registered (default stays 1.0.3-hotfix) - #255

Closed
88plug wants to merge 2 commits into
mainfrom
claude/agentstack-eat-release-1-1-0
Closed

88plug wants to merge 2 commits into
mainfrom
claude/agentstack-eat-release-1-1-0

Conversation

@88plug

@88plug 88plug commented Oct 29, 2026

Copy link
Copy Markdown
Owner

What changed and why

Intel's current EAT release is release-1.1.0: tag commit 0c726f576595971c53cc45b94e08ba969beb4a4a, published 2026-10-22, prerelease=false, the merge of EAT PR #21 (https://github.com/intel/enterprise-agent-toolkit/releases/tag/release-1.1.0). The tag k3d-gpu ships, release-1.0.3-hotfix (0d3438d7119de44cafc5903f66665c0b623e3333), is now flagged prerelease=true on GitHub (gh api repos/intel/enterprise-agent-toolkit/releases, read 2026-10-29). On main, eat-up.sh hard-coded the 1.0.3 tag and commit, so no k3d-gpu path reached 1.1.0's agent-stack changes (Qwen3Guard, the semantic router, OpenShell, Kata, NUMA-aware NRI balloons, the Arc XPU path, vLLM CPU v0.28.0).

This PR makes release-1.1.0 deployable with EAT_RELEASE=release-1.1.0, with its checks in place:

  • eat-up.sh: EAT_RELEASE resolves from a table: release-1.0.3-hotfix (default, 0d3438d, no image overlay) or release-1.1.0 (0c726f5, image overlay vllm-image-release-1.1.0.yaml). Any other value is refused before the config or the cluster is read; there is no main entry (EAT main 4a2e930 is 1.1.0 plus one PNG, feat: detect Alder/Raptor/ADL-N/Arrow Lake iGPUs, NPU gen, ISA, XMX and media engines #27). The clone uses --branch "${EAT_RELEASE}" and the commit check names the release, the expected commit and the found HEAD, so an EAT_WORK cloned for one release is refused for the other. openshell_setting became config_setting <cfg> <key> with EAT's read_config_file parse rules. Before the kubeconfig check:
    • deploy_openshell=on: refused on 1.0.3 (names release-1.1.0), passed on 1.1.0.
    • deploy_nri_balloon_policy: refused unless off/no on both releases. Both turn EAT's policy on when the key is absent (parse-user-prompts.sh:55-60 at 0d3438d, :55-66 at 0c726f5, with compute_platform's default cpu), and it would be a second policy beside k3d-gpu's.
    • 1.1.0 only: compute_platform=xpu|x refused (deploy-intel-gpu-plugin.yml applies intel-device-plugins' gpu_plugin from main, unpinned, beside k3d-gpu's; points to K3D_GPU_AGENT_BACKEND=vllm), deploy_kata_containers=on refused (no /dev/kvm in a k3d node), and rack_scale_mode=on refused. The last one is beyond the brief: rack-scale mode in brownfield runs the rack-profile parser, netplan and BGP, and deploys the NVIDIA GPU operator for GPU nodes in the profile (fresh-install.sh:225-243), which would be a second GPU plugin.
    • deploy_guardrails=on: refused on 1.0.3 (no guardrail role), passed on 1.1.0 (opt-in below).
    • The overlay is mounted as -v <file>:/vllm-image-values.yaml:ro -e EAT_VLLM_IMAGE_VALUES=/vllm-image-values.yaml.
  • vllm-image-release-1.1.0.yaml (new): vllm/vllm-openai-cpu v0.28.0@sha256:197354e6475e638eb5ccca09beb078488046a82de0e204e7429bf1a804df9647, the index digest recorded in crescent amendment E1, re-verified with scripts/images-lock digest docker.io/vllm/vllm-openai-cpu:v0.28.0 on 2026-10-29. Source: EAT 0c726f5 core/helm-charts/vllm/xeon-values.yaml:34 (and guardrail-values.yaml:30).
  • vllm-merge.py (new, executable): the inline merge from brownfield.sh moved to a file. It merges EAT's values <- EAT_VLLM_VALUES <- EAT_VLLM_IMAGE_VALUES, sets VLLM_CPU_KVCACHE_SPACE as before, and exits non-zero naming both tags when the merged tag's version (before @) differs from the tag in EAT's own file. On EAT 0d3438d's real xeon-values.yaml its output is byte-identical to the old inline merge (sha256 ed3bf65f... for both). On 0c726f5's real file: with the overlay, v0.28.0@sha256:197354e6..., KV set on 17 of 17 entries, memory 16Gi / cpu "8" / balloon performance kept; without it, refused. EXPERIMENTS.md amendment E1 records why: v0.28.0 contains vllm#45844 (26eb8720, the Gemma 4 split-KV fix) and v0.24.0 does not.
  • brownfield.sh:
    • Guardrail switch. EAT 0c726f5 deploy-agentic-stack.sh:195 sets DEPLOY_GUARDRAILS="${DEPLOY_GUARDRAILS:-on}" at top level, which runs when brownfield.sh sources it with DEPLOY_SOURCED=1. The deploy_guardrails key is read only in main() (:1136-1140), which a sourced run skips, and fresh-install.sh:419 then deploys the guard. brownfield.sh now exports DEPLOY_GUARDRAILS from the config key before sourcing: on for on|yes, else off, whatever the environment says. It is harmless on 1.0.3, which has no reader.
    • Pinned guardrail opt-in. I read deploy-guardrails.yml and its vars_files at 0c726f5. remote_helm_charts_base comes from inference_common.yml and is used in that playbook only at lines 115, 133 and 135: the guard's guardrail-values.yaml and the vllm chart. No role it includes (utils) and not the imported register-guardrail-genai-gateway.yml read it, so the override is scoped to the guard. The ansible-playbook() wrapper passes deploy-guardrails.yml alone --extra-vars @~/k3d-gpu-guard-vars.yml, pointing at a copy of EAT's vllm chart whose guardrail-values.yaml carries the overlay's digest (vllm-merge.py --require-digest). It records a marker file and fails if the playbook bypassed it, like the gateway. With the guard on and no overlay, it stops before EAT runs.
    • Model mode calls vllm-merge.py.
    • eat-opt.py already reads the version from the merged values (eat-opt.py:43-46, :124; 0.24.0 is only a fallback). The new test confirms it reports 0.28.0, and the file is unchanged.
    • The overlay keys are still read by 1.1.0's chart: memory, cpu, cpu_balloon_annotation and image (0c726f5 templates/deployment.yaml:26-27, :144, :222-239; that file also adds memoryLimit and falls back to optimal_cpu_cores).
  • agentic-config.cfg: deploy_guardrails=off, with a comment that 1.1.0 ships it on and that here Qwen3Guard is opt-in. deploy_nri_balloon_policy=off is kept.
  • images.lock: the docker.io/vllm/vllm-openai-cpu v0.28.0 entry, inserted between v0.24.0 and v0.32.0. Nothing else changed.
  • Docs: the EAT section of docs/platforms.md (the stale rationale replaced, the prerelease flag noted, the OpenShell paragraph, the guardrail and vLLM-image bullets now describe what k3d-gpu does, and the ci: run the host-setup, KubeRay and simulated-hardware suites #21 row's Impact and Action cells updated). Also the "EAT 1.1.0" planned bullet in docs/intel.md (merged by hand with docs: state what ran on the Xeon 6741P instead of "simulated sysfs only" #246's adjacent change), and integrations/eat/README.md (a new "EAT releases" section with the per-release refusal table and the guardrail opt-in, plus the new files in the file table). docs/intel/technical-report.md now counts 20 PENDING rows, because ledger_drift_check requires the count. H1c is cited as plain text "EXPERIMENTS.md H1c (pending)".
  • EXPERIMENTS.md: H1c pre-registered, PENDING. I confirmed first that "H1c" was unused on origin/main and in open PRs. The row sits after H1b's, and the section ### H1c pre-registration (i9-13900T, 2026-10-29) sits after ### H1b run. H1c reuses H1b's protocol, load, grading, lock budget and outcome table, with EAT_RELEASE=release-1.1.0 and the cluster k3dgpu-h1c-eat. It adds three predictions, read as step 4p: the vLLM pod runs vllm/vllm-openai-cpu@sha256:197354e6...; no vllm-guard Helm release or guardrails namespace exists; exactly one nri-resource-policy* DaemonSet exists (k3d-gpu's), with no Helm release for it. No existing row or section was changed.

Default unchanged, and why

The default stays release-1.0.3-hotfix. With default settings, behaviour on 1.0.3 is unchanged: the same commit, and the same merged values (byte-identical, above) from vllm-values.yaml alone. The default flips in a later PR, once H1c is SUPPORTED. This leaves every pending ledger arm untouched: no pending row runs eat-up.sh, H54q renders from its own 0d3438d checkout through bench/h54, and H7x uses bench/apb/h7x.sh at 0c726f57 with its own vLLM tag. integrations/eat/vllm-values.yaml, bench/**, crescent, wildct and the desktop holds are not touched.

H1c is pending; nothing has run live on 1.1.0

Nothing in this PR has run against a release-1.1.0 stack. There are no performance numbers. The checks are stub-based (tests/eat_test.sh). The source path was also dry-run read-only, below.

Dry run: brownfield.sh's source path against a 0c726f5 checkout

I built the bastion image from integrations/eat/bastion.Dockerfile and ran it with --network none, as uid 1000, against a copy of the 0c726f5 tree. The script exported DEPLOY_GUARDRAILS=off, ran set --; DEPLOY_SOURCED=1 source ./deploy-agentic-stack.sh; _source_core_libs, then resolved each function by name:

DEPLOY_GUARDRAILS after sourcing: off
GUARDRAIL_MODEL: Qwen/Qwen3Guard-Gen-0.6B
_source_core_libs brownfield_deployment manage_kubeconfig detect_kubernetes_platform
prompt_kubernetes_platform read_config_file prompt_for_input setup_initial_env setup_bastion
run_setup_bastion_playbook deploy_inference_llm_models_playbook fresh_installation
execute_and_check deploy_guardrails_controller deploy_openshell_controller
deploy_kata_containers_controller run_deploy_intel_gpu_plugin_playbook
deploy_nri_balloons_playbook sync_repo_to_kubespray       -> all "function"
functions missing: 0
playbook present: deploy-genai-gateway.yml, deploy-guardrails.yml, deploy-inference-models.yml

The same run with DEPLOY_GUARDRAILS unset prints DEPLOY_GUARDRAILS after sourcing: on, which is the default this PR overrides.

Checks (all pass on this branch, rebased on main e5748cd)

shellcheck v0.11.0 --severity=warning integrations/eat/eat-up.sh integrations/eat/brownfield.sh tests/eat_test.sh: clean
tests/eat_test.sh                         149 passed, 0 failed
tests/platforms_doc_test.sh               195 passed, 0 failed
tests/ci_wiring_test.sh                   69 passed, 0 failed
tests/bench_test.sh                       71 passed, 0 failed
scripts/images-lock check                 ok   images.lock matches share/, the Dockerfile, scripts/k3d-gpu, integrations/eat and k3s v1.37.1-k3s1
scripts/images-lock pins                  ok   every image reference is pinned by digest or allowed in images.unpinned
tests/image_pins_test.sh                  43 passed, 0 failed
tests/claims_check_test.sh                81 passed, 0 failed
tests/claims_check.sh                     claims_check: 26 file(s) clean
python3 tests/ledger_drift_check_test.py  OK
python3 tests/ledger_drift_check.py       ledger_drift_check: 41 file(s) agree with 82 ledger rows
tests/pe_premise_check_test.sh            16 passed, 0 failed
tests/pe_premise_check.sh                 pe_premise_check: ok
tests/docs_test.sh                        63 passed, 0 failed   (python:3.14.8-slim by digest, docs-build/requirements.txt --require-hashes)
mkdocs build --strict                     rc=0

I wrote the new tests/eat_test.sh cases before the implementation and watched them fail (68 failures) for the expected reasons: the old messages, no release table, no vllm-merge.py, and model mode silently merging v0.24.0 over 1.1.0's values.

The new cases:

  • the release table: unknown values refused before the config and the kubeconfig, and unset or empty means the default
  • the per-release key matrix, using the openshell spellings (spaces, quotes, indent, last assignment wins)
  • the commit check without network: a stub kubectl and a real local repo at another commit; a docker stub fails the test if eat-up.sh gets to docker build
  • the bastion mounts per release, and cross-release EAT_WORK refusal (stub git)
  • brownfield.sh stack mode against a stub EAT whose deploy-agentic-stack.sh sets DEPLOY_GUARDRAILS="${DEPLOY_GUARDRAILS:-on}" at top level:
    • the shipped config and no key give off, as does DEPLOY_GUARDRAILS=on in the environment with the key off
    • deploy_guardrails=on gives on, the chart-copy extra var, and the copied guardrail-values.yaml at v0.28.0@sha256:197354e6...
    • a renamed guard playbook fails the deploy
  • model mode on both releases, with and without the overlay
  • vllm-merge.py on the 0d3438d and 0c726f5 fixture shapes
  • eat-opt.py on merged v0.28.0 values: it reports vLLM 0.28.0, and its choices are computed from console/model_opt.py for 0.28.0. The existing v0.24.0 case is unchanged.
  • Section 1's mode check now also covers integrations/eat/*.py.

…8.0 by digest, Qwen3Guard opt-in

Intel published EAT release-1.1.0 on 2026-10-22 (0c726f5, the merge of EAT #21)
and GitHub now flags release-1.0.3-hotfix as a prerelease. eat-up.sh could reach
only 0d3438d. It now resolves EAT_RELEASE from a table: release-1.0.3-hotfix
(default, unchanged) or release-1.1.0, each pinned to its commit; any other value is
refused before the config or the cluster is read, and an EAT_WORK cloned for one
release is refused for the other.

The config is checked against the release before the cluster is touched, parsed as
EAT's read_config_file parses it: deploy_openshell and deploy_guardrails only where
the release has the role; deploy_nri_balloon_policy anything but off or no on both
releases, since both turn EAT's balloons policy on when the key is absent; and on
release-1.1.0, compute_platform=xpu (an unpinned GPU plugin from intel-device-plugins
main beside k3d-gpu's), deploy_kata_containers=on (no /dev/kvm in a k3d node) and
rack_scale_mode=on.

release-1.1.0 moves every EAT vLLM CPU path to v0.28.0, by tag only. eat-up.sh
mounts vllm-image-release-1.1.0.yaml (v0.28.0 at its index digest 197354e6...) for
that release, and brownfield.sh merges it last through vllm-merge.py, the old inline
merge moved to a file. vllm-merge.py refuses a merged tag whose version differs from
the one EAT's own values name, so 1.1.0's model configs never run on v0.24.0. On
release-1.0.3-hotfix the merged values are byte for byte what the inline merge wrote.

release-1.1.0's deploy-agentic-stack.sh sets DEPLOY_GUARDRAILS=on at top level
(line 195), which runs when brownfield.sh sources it, and reads deploy_guardrails
only in main(). brownfield.sh now exports DEPLOY_GUARDRAILS from the config key
before sourcing (off unless on or yes), and the shipped config sets it off. With it
on, deploy-guardrails.yml alone gets remote_helm_charts_base pointing at a copy of
EAT's vllm chart whose guardrail-values.yaml carries the digest, with a marker file
that fails the deploy if the playbook bypasses the copy.

images.lock lists the v0.28.0 digest. tests/eat_test.sh covers the release table,
the per-release key matrix, the commit check offline, the bastion mounts, the guard
switch and pin, model mode on both releases, vllm-merge.py, and eat-opt.py on the
merged v0.28.0 values against console's optimizer for that version.
…pre-registered

docs/platforms.md (EAT section), docs/intel.md and integrations/eat/README.md now say
what k3d-gpu does with EAT release-1.1.0: eat-up.sh deploys it with
EAT_RELEASE=release-1.1.0, the default stays release-1.0.3-hotfix (now a GitHub
prerelease), the guardrail is opt-in with its image by digest, the vLLM CPU image is
v0.28.0 by digest with a tag check, and the colliding keys are refused. The stale
rationale that pending rows pinned 0d3438d through eat-up.sh is replaced: no pending
row runs eat-up.sh. Nothing has run against a 1.1.0 stack yet, and no performance
number is stated.

EXPERIMENTS.md pre-registers H1c, PENDING: H1b's run repeated with
EAT_RELEASE=release-1.1.0 on a fresh cluster k3dgpu-h1c-eat, plus three added
predictions (the vLLM pod on the v0.28.0 digest, no vllm-guard release, exactly one
nri-resource-policy-balloons DaemonSet, k3d-gpu's). A SUPPORTED H1c is the gate for
making release-1.1.0 the default. No existing row or section changes;
docs/intel/technical-report.md counts 20 PENDING rows.
@88plug

88plug commented Oct 29, 2026

Copy link
Copy Markdown
Owner Author

Superseded by #250 (same change, carries the F4 pre-registration). Closing to avoid a duplicate EAT 1.1.0 path.

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