Skip to content

fix(cache): merge CacheRuntime resources onto the CacheRuntimeClass baseline - #6177

Open
btxu-db wants to merge 23 commits into
fluid-cloudnative:masterfrom
btxu-db:fix/cacheruntime-merge-partial-resources
Open

btxu-db wants to merge 23 commits into
fluid-cloudnative:masterfrom
btxu-db:fix/cacheruntime-merge-partial-resources

Conversation

@btxu-db

@btxu-db btxu-db commented Sep 1, 2026 •

Copy link
Copy Markdown
Contributor

Ⅰ. Describe what this PR does

A CacheRuntime that names only some resource keys loses every requirement it does not
restate. The practical case is an owner who wants to raise one number: patching just
limits.memory on a worker whose CacheRuntimeClass template declares a full set leaves the
container with no CPU request and no CPU limit at all.

$ # template: requests {cpu 1, memory 2Gi}, limits {cpu 2, memory 4Gi}
$ kubectl patch cacheruntime restest --type=merge \
    -p '{"spec":{"worker":{"resources":{"limits":{"memory":"8Gi"}}}}}'

gen = 1  {"limits":{"cpu":"2","memory":"4Gi"},"requests":{"cpu":"1","memory":"2Gi"}}
gen = 2  {"limits":{"memory":"8Gi"}}

There is no error and no event. The scheduler stops reserving CPU for the worker and nothing
caps its CPU on the node; requests.memory then comes back as 8Gi because Kubernetes
defaults requests to limits, silently tripling the memory reservation the template asked for.

Why it happens. The CacheRuntimeClass template and the CacheRuntime are treated as
alternatives — one or the other, never both. Two places make that assumption, and they have
to agree, because one renders the workload and the other rebuilds the desired state on every
reconcile:

// transform_common.go:130 — creation
if runtimeCompSpec.Resources.Limits != nil || runtimeCompSpec.Resources.Requests != nil {
    podTemplate.Spec.Containers[0].Resources = runtimeCompSpec.Resources   // whole struct
}

// sync.go:239 — every reconcile
if runtimeResources.Requests != nil || runtimeResources.Limits != nil {
    return runtimeResources.DeepCopy()                                     // whole struct
}

ResourceRequirements carries Limits, Requests and Claims, so replacing it wholesale
discards all three. updateResources (advanced_statefulset_manager.go:289) then writes that
value onto the container, which is correct at its own level — it is handed a complete desired
state and has no way to know part of it went missing upstream.

Approach. The two are not alternatives. The template carries the runtime's own
requirements; the CacheRuntime expresses the deltas an owner wants for their instance. This PR
overlays them key by key through one helper, mergeResourceRequirements, that both paths call,
so the creation path and the sync path cannot drift apart and leave the workload rolling on
every reconcile. Limits and Requests merge by resource name; Claims by claim name, with
the template's order preserved and unnamed claims appended.

updateResources is left alone deliberately. It receives a fully resolved desired state, and
teaching the workload layer about the CacheRuntimeClass would put the template in two places.

The resolved value depends only on the current template and the current CacheRuntime: per
key, the CacheRuntime's value if it names one, otherwise the template's, and a key neither
declares is cleared. desiredComponentResources therefore no longer returns nil ("leave the
workload untouched", introduced in #6165). That nil existed to keep the template's values when
the CacheRuntime sets none; the merge now does that on its own, and the nil had only one
effect left — a value could not be removed once neither side declared anything. An empty list
such as limits: {} names no key, so it reads the same as leaving limits out. (Convergence is
unaffected: Semantic.DeepEqual treats nil and empty maps as equal, so a freshly created
workload is not patched on its first sync.)

Master, worker and client all go through transformComponentPodTemplate on creation. Only
master and worker are synced, since client runs as a DaemonSet and is deliberately not synced.

Ⅱ. Does this pull request fix one issue?

fixes #6173

Ⅲ. List the added test cases (unit test/integration test) if any, please explain if no tests are needed.

transform_common_test.go is new and covers the helper and the resolver directly:

  • mergeResourceRequirements — an overlay naming one key moves it and keeps the rest of the
    baseline; an overlay naming a key the baseline does not declare adds it; neither side
    declaring anything leaves the lists nil; the baseline it is handed is not mutated; claims
    are kept, replaced by name, and appended.
  • desiredComponentResources — resolves to the template when the CacheRuntime sets nothing;
    keeps the template's other requirements when the CacheRuntime only raises the memory limit
    (the reported case); resolves to empty resources when neither declares anything; resolves to the CacheRuntime
    when only it declares; does not mutate the CacheRuntimeClass template.

Two specs in sync_test.go drive the whole sync against a fake client, under
"when the CacheRuntime only names part of the template's resources":

  • "should move the key it names and keep the template's other requirements". The end-to-end
    form of the report — full template, limits.memory raised on the CacheRuntime, CPU request,
    CPU limit and memory request expected to survive. Copying this spec into a worktree at the
    base commit — test present, fix absent — fails on the CPU limit with
    Expected <string>: 0 to equal <string>: 2, i.e. the container has no CPU limit at all,
    which is the reported symptom.
  • "should leave requests unset and stop patching once converged". Requests the merge has
    nothing to carry over for stay unset, and a second sync leaves the workload's
    resourceVersion alone.

Further sync_test.go specs: the same partial override on the master; "should clear the
workload's resources"
(empty template, workload carrying 8Gi, CacheRuntime declaring nothing);
and "should restore the template value when the CacheRuntime specifies none", which is the
"remove an override, fall back to the template" case. Restoring the nil return fails the
clear spec and the empty case in transform_common_test.go.

resources_equivalence_test.go pins the invariant the shared helper is meant to give: for a
table of template/CacheRuntime combinations (neither side, either side, a partial override, a
key the template lacks, empty lists on either side, claims on both), the creation path
(transformComponentPodTemplate) and the sync path (desiredComponentResources) resolve to
the same resources, and a workload rendered by the former is not patched by syncRuntimeSpec.
Reverting either path to the old wholesale replace fails it.

The curvine e2e suite (test/gha-e2e/curvine) now declares a full set of resources on the
worker template, patches only limits.memory on the CacheRuntime, and checks that the
AdvancedStatefulSet rolls out with the new limit while keeping the template's CPU limit and
requests.

The existing syncRuntimeSpec specs from #6165 pass unchanged, which is the evidence that the
"template value when the CacheRuntime sets nothing" behaviour is preserved.

Ⅳ. Describe how to verify it

FLUID_UNIT_TEST=true go test -gcflags="all=-N -l" ./pkg/ddc/cache/...

On a cluster, with the manifests from #6173 — a template declaring
requests {cpu 1, memory 2Gi} and limits {cpu 2, memory 4Gi}, and a CacheRuntime that
patches limits.memory to 8Gi:

kubectl get advancedstatefulset restest-worker \
  -o jsonpath='{.spec.template.spec.containers[0].resources}'

A CacheRuntime that sets no resources at all stays on the template values across reconciles,
unchanged from #6165. With a template that declares no resources, setting limits.memory on the
CacheRuntime and then removing it again clears the limit from the workload.

Ⅴ. Special notes for reviews

Semantics. This implements the two rules proposed in the
#6165 review:

  1. if the CacheRuntimeClass sets a default resource, the user cannot remove it — the non-nil
    value from the CacheRuntime or the CacheRuntimeClass is taken, key by key;
  2. if the CacheRuntimeClass does not set it, the user can set the resource and later remove it.

Behaviour changes compared with master, all documented in
docs/{en,zh}/samples/cacheruntime/cacheruntime_spec_update.md:

  • a CacheRuntime that names part of resources keeps the template's other keys ([BUG]CacheRuntime: a partially specified resources silently drops the rest of the container's resource requirements #6173);
  • removing an override falls back to the template's value, or clears the key when the template
    does not declare it (on master, with a template that declares no resources, the workload
    kept the old value);
  • a key neither side declares is cleared, so resources edited directly on the AdvancedStatefulSet
    are reverted on the next reconcile (on master they were kept when neither side declared any);
  • edits to the template's resources reach existing instances on their next reconcile, for the
    keys the CacheRuntime does not override;
  • a CacheRuntime that sets only claims is no longer ignored; a claim must reference a pod-level
    resourceClaims entry the template declares, otherwise the API server rejects the Pod.

Upgrade note. A workload created by an earlier release from a partially specified
CacheRuntime is missing the template's other requirements. The first reconcile after upgrade
restores them, which updates those pods once (in place where the cluster can resize them,
otherwise by recreating them). The end state is the intended one; the update is the repair.

Distinct from #6161 despite landing on the same lines. #6161 is "the CacheRuntime specifies no
resources at all and the template's values get cleared", fixed by #6165 with a nil check. A
partially filled value is still non-nil, so it survives that fix — the reproduction above was
run on a build that already contains #6165. Also distinct from #6166: that one is about the
tiered store quota being dropped from the container's memory accounting, this one about the
rest of the requirements being dropped from the workload. They share the code path but neither
fix depends on the other. This PR is based on a master that already contains #6167: the tiered
store memory quota is charged on top of the merged baseline.

@fluid-e2e-bot

fluid-e2e-bot Bot commented Sep 1, 2026

Copy link
Copy Markdown

[APPROVALNOTIFIER] This PR is NOT APPROVED

This pull-request has been approved by:
Once this PR has been reviewed and has the lgtm label, please assign cheyang for approval by writing /assign @cheyang in a comment. For more information see:The Kubernetes Code Review Process.

The full list of commands accepted by this bot can be found here.

Details Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@fluid-e2e-bot

fluid-e2e-bot Bot commented Sep 1, 2026

Copy link
Copy Markdown

Hi @btxu-db. Thanks for your PR.

I'm waiting for a fluid-cloudnative member to verify that this patch is reasonable to test. If it is, they should reply with /ok-to-test on its own line. Until that is done, I will not automatically test new commits in this PR, but the usual testing commands by org members will still work. Regular contributors should join the org to skip this step.

Once the patch is verified, the new status will be reflected by the ok-to-test label.

I understand the commands that are listed here.

Details

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes/test-infra repository.

@btxu-db
btxu-db force-pushed the fix/cacheruntime-merge-partial-resources branch 2 times, most recently from 766461f to c6277f4 Compare September 1, 2026 16:13
@codecov

codecov Bot commented Sep 1, 2026 •

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 93.00699% with 10 lines in your changes missing coverage. Please review.
✅ Project coverage is 65.72%. Comparing base (e0fc4c1) to head (a773dfa).
⚠️ Report is 15 commits behind head on master.

Files with missing lines Patch % Lines
pkg/ddc/cache/engine/sync.go 79.16% 8 Missing and 2 partials ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##           master    #6177      +/-   ##
==========================================
+ Coverage   65.45%   65.72%   +0.26%     
==========================================
  Files         486      486              
  Lines       34307    34480     +173     
==========================================
+ Hits        22455    22661     +206     
+ Misses      10091    10064      -27     
+ Partials     1761     1755       -6     

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

// returns it. Callers own base: mergeResourceRequirements hands over a deep copy. A nil
// base is kept nil when the overlay declares nothing, so that an untouched component
// still compares equal to the workload it was rendered into.
func mergeResourceList(base, overlay corev1.ResourceList) corev1.ResourceList {

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

modifying it in place or returns it. modified in place and return it is not a design.


// mergeResourceClaims applies the overlay claims onto base by name, modifying it in
// place, and returns it.
func mergeResourceClaims(base, overlay []corev1.ResourceClaim) []corev1.ResourceClaim {

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same as line 181

…aseline

A CacheRuntime that names only some resource keys used to replace the
container's whole ResourceRequirements, dropping every requirement it did
not restate. Raising just limits.memory also cleared limits.cpu,
requests.cpu, requests.memory and claims, leaving the container with no CPU
request and no CPU limit at all, and letting Kubernetes default the memory
request up to the new limit.

Both the creation and the update path treated the CacheRuntime resources
and the CacheRuntimeClass template as alternatives. They are not: the
template carries the runtime's own requirements and the CacheRuntime
expresses the deltas an owner wants for their instance. Overlay them key by
key instead, through one helper both paths call, so the two cannot drift
apart and leave the workload rolling on every reconcile.

The corollary is that a key set by the template can now be overridden but no
longer removed by omitting it from the CacheRuntime. Removing a requirement
is a change to the template, which is where the runtime's requirements are
described. This is the same semantic question raised in the review of

Fixes fluid-cloudnative#6173

Signed-off-by: btxu-db <btxu-db@outlook.com>
…eSpec

The unit specs pin mergeResourceRequirements and desiredComponentResources
directly. These drive the whole sync against a fake client instead, so the
reported scenario is covered end to end: a worker whose CacheRuntimeClass
template declares a full set of requirements and whose CacheRuntime raises
only limits.memory keeps its CPU request, CPU limit and memory request.
Removing the merge fails it with the value the issue reports.

A second spec pins the nil handling. When neither side declares requests the
merged value must leave them nil rather than an empty map: Semantic.DeepEqual
separates the two, so an empty map would never compare equal to the workload
and the sync would patch on every reconcile. Dropping the empty-overlay guard
in mergeResourceList fails it.

Signed-off-by: btxu-db <btxu-db@outlook.com>
The spec update guide described resources as the CacheRuntime value or, when
unset, the CacheRuntimeClass template value. They are a baseline and an
overlay now, so record that, and restate the limitation it carries: a key the
template declares can be overridden but no longer removed by omitting it.

Signed-off-by: btxu-db <btxu-db@outlook.com>
…out returning

mergeResourceList and mergeResourceClaims modified base in place and also
returned it, so a caller could not tell from the signature whether base was
left untouched, and had to use the returned value to pick up a list
allocated from nil or a slice grown by append.

Both now take a pointer and modify it in place without returning. The nil
case is handled inside: mergeResourceList allocates *base only when the
overlay declares something, keeping an untouched nil list nil, and
mergeResourceClaims relies on append growing a nil *base.
mergeResourceRequirements keeps its signature: it still deep-copies the
template baseline and returns the merged value, so its callers are
unchanged. Its comment is condensed to the overlay rule it implements.

Signed-off-by: btxu-db <btxu-db@outlook.com>
The resources row pinned the replace-the-whole-struct behaviour as a known
bug of fluid-cloudnative#6173. With the resources now overlaid on the CacheRuntimeClass
template key by key, it expects what that row said it should become:
requests {cpu 1, memory 2Gi} and limits {cpu 2, memory 8Gi} on both the
create and the update path.

Signed-off-by: btxu-db <btxu-db@outlook.com>
@btxu-db
btxu-db force-pushed the fix/cacheruntime-merge-partial-resources branch from c6277f4 to 0601908 Compare September 30, 2026 07:46
Drop the doubled blank line left where the rebase onto fluid-cloudnative#6188 joined the
existing specs and the resources specs, which failed the gofmt check.

Signed-off-by: btxu-db <btxu-db@outlook.com>

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

Empty resource maps can no longer clear runtime-only values, and removing the final template requirement leaves stale workload resources.

2 open findings
What changed in this PR

Fixes partial CacheRuntime resource overrides by merging them with the CacheRuntimeClass baseline.

Changes:

  • Adds key-level merging for requests, limits, and claims.
  • Aligns creation and reconciliation paths with regression coverage.
  • Documents the new overlay semantics.
File Description
pkg/​ddc/​cache/​engine/​transform_common.go Adds resource merging helpers.
pkg/​ddc/​cache/​engine/​transform_common_test.go Tests merge and resolution behavior.
pkg/​ddc/​cache/​engine/​sync.go Uses merged resources during reconciliation.
pkg/​ddc/​cache/​engine/​sync_test.go Tests partial overrides and convergence.
pkg/​ddc/​cache/​engine/​composition_matrix_test.go Updates cross-path expectations.
docs/​en/​samples/​cacheruntime/​cacheruntime_spec_update.md Documents English merge semantics.
docs/​zh/​samples/​cacheruntime/​cacheruntime_spec_update.md Documents Chinese merge semantics.

🧠 Review effort: Balanced


Give feedback about Copilot approvals in this survey to enter a drawing for a $150 gift card.

Comment on lines +205 to +215
func mergeResourceList(base *corev1.ResourceList, overlay corev1.ResourceList) {
if len(overlay) == 0 {
return
}
if *base == nil {
*base = corev1.ResourceList{}
}
for name, quantity := range overlay {
(*base)[name] = quantity.DeepCopy()
}
}
Comment thread pkg/ddc/cache/engine/sync.go Outdated

@cheyang cheyang left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Two independent reviews with separate verification harnesses both reproduced #6173 on the merge base (a partially specified CacheRuntime resources wholesale-replaces the template's requirements, dropping requests.cpu, requests.memory, limits.cpu and claims at both the creation render and the sync resolver) and both confirm the fix at head, including convergence — the two reviewers found no blocking issues and agree on every point. What's left before merge: (1) an explicit maintainer ack of the settled semantics — template keys can now be overridden but not removed by omission, with one unstated edge where removing the final key from the template leaves the old value on the workload — which the author themselves asked to have confirmed; (2) a docs sentence for the one-time repair roll after upgrading and the newly template-live propagation of CacheRuntimeClass edits; (3) an e2e spec-update case in the curvine suite, plus a small creation/sync equivalence test to pin the shared-helper invariant. Copilot (advisory) flags the same nil/empty-boundary family and its removal-edge flag is confirmed by both reviewers.

@@ -248,28 +248,26 @@ func (e *CacheEngine) syncRuntimeSpec(ctx cruntime.ReconcileRequestContext, runt
}

// desiredComponentResources resolves the resources that should be synced to a

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Consensus (both reviewers, confirmed in cross-critique): two operator-visible consequences of the new baseline model are absent from the shipped docs. (1) A workload created by an earlier release from a partially specified CacheRuntime is missing the template's other requirements; the first reconcile after upgrade restores them and rolls/resizes those pods once — the PR body says "the roll is the repair", but the docs give no warning. (2) A CacheRuntimeClass resource edit now re-propagates on every reconcile to runtimes that partially override resources (previously a runtime declaring anything never saw template changes; resources are now uniquely template-live, more so than image, which sync reads from RuntimeVersion). One sentence in cacheruntime_spec_update.md or a release note would cover both.

func mergeResourceRequirements(base, overlay corev1.ResourceRequirements) corev1.ResourceRequirements {
merged := *base.DeepCopy()
mergeResourceList(&merged.Limits, overlay.Limits)
mergeResourceList(&merged.Requests, overlay.Requests)

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Consensus (Codex F1, confirmed and sharpened by Claude): the base guards keyed on Limits/Requests being non-nil, so a CacheRuntime declaring only claims was silently dropped; mergeResourceRequirements now merges claims unconditionally. Since the cache engine never renders pod-level resourceClaims, every runtime-declared claim is unmatched, and upstream pod validation (validateResourceClaimNames) rejects it — a claims-only CacheRuntime now surfaces as a loud, recurring validation failure at pod creation or workload patch time. Arguably better than the old silent drop and within the issue's scope (claims were dropped too), but this failure mode is not called out in the docs or PR body.

return runtimeResources.DeepCopy()
var templateResources corev1.ResourceRequirements
if componentDefinition != nil && len(componentDefinition.Template.Spec.Containers) > 0 {
templateResources = componentDefinition.Template.Spec.Containers[0].Resources

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Consensus (Codex F2, confirmed by Claude with the live consequence dissolved): the guard tests Requests/Limits/Claims == nil rather than len() == 0, so a template storing an explicitly empty map resolves to a non-nil desired containing an empty map. This is a pre-existing pattern, not introduced here, and it converges anyway: updateResources compares via equality.Semantic.DeepEqual, which equates nil and empty maps, so an empty-map desired never produces a patch. A len()-based check would have been more robust; noting it for a future cleanup only.

2. the `resources` set on the CacheRuntime are overlaid on that baseline key by key —
`requests` and `limits` merge by resource name, `claims` by claim name;
3. when neither declares anything, nothing is synced and the workload keeps its current resources.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Consensus (Claude F1 = Codex F3, confirmed both ways; Copilot agrees and sharpens): once merged, a key the CacheRuntimeClass template declares can be overridden but no longer removed by omitting it from the CacheRuntime — dropping a requirement means editing the template. The template-as-baseline reading looks right (the null-sentinel alternative is an API change, correctly out of scope), the docs state it in en and zh, and the PR body itself asks for confirmation — but this field-level semantic change deserves an explicit maintainer ack before it ships. Note the documented removal recipe has one unstated boundary (verified by both reviewers, flagged by Copilot): removing the final key from the template resolves to an all-nil desired, desiredComponentResources returns nil, and SyncComponentSpec skips resources entirely (advanced_statefulset_manager.go newSpec.Resources != nil guard), so the deleted value stays on the workload; removing a non-final key works. The ack should be made aware of this edge.

// Issue #6173: a CacheRuntime that names one key used to replace the container's
// whole ResourceRequirements, so raising the memory limit alone left the container
// with no CPU request and no CPU limit at all.
Context("when the CacheRuntime only names part of the template's resources", func() {

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Consensus (Claude F3 = Codex F4, reached independently): the PR's coverage is unit + fake-client integration (sync_test.go drives the whole syncRuntimeSpec including a convergence spec — good, and it matches the convention #6165 set for this same code path), but the gha-e2e curvine suite covers create/bind/IO only. The whole in-place-update feature line (#6165, #6167, this PR) is untested against a real cluster, and this PR is the cheapest place to add the case (patch a CacheRuntime's resources, assert the workload keeps the template's other keys) since it defines the observable contract the docs now advertise.

return existing
}

// mergeResourceRequirements overlays the CacheRuntime component resources onto the

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Consensus (Claude F4, confirmed by Codex): the PR's central design argument — both paths call one helper, so they cannot drift apart — is not asserted by any test; each path is tested separately. A small table test comparing transformComponentPodTemplate's rendered resources against desiredComponentResources for the same inputs would pin the invariant (a working candidate, TestP1CreationAndSyncAgree, exists on branch verify/cache-resources-merge-claude: passes at head, fails at base on the claims case). The new sync specs cover worker only; master shares desiredComponentResources, so one master spec would make coverage symmetric.

The comment on mergeResourceList, and the one on the "stop patching once
converged" spec, said an empty list would never compare equal to a
workload rendered with nil, so the sync would patch on every reconcile.
That is not so: updateResources compares with equality.Semantic, which
treats nil and empty maps as equal.

What the nil actually protects is the fluid-cloudnative#6165 contract. When neither side
declares resources, desiredComponentResources returns nil and the sync
leaves the workload alone. Allocating empty lists there turns that into
a non-nil empty requirement, and the sync clears the resources of a
workload edited out of band. Dropping the guard fails the specs that pin
this, not the convergence spec. Say so in both comments.

Signed-off-by: btxu-db <btxu-db@outlook.com>
transformComponentPodTemplate and desiredComponentResources both resolve
a component's resources through mergeResourceRequirements, but each
path was only tested on its own. Nothing asserted that they agree, which
is what keeps the first reconcile after creation from patching the
workload it has just rendered.

Replay a table of template and CacheRuntime resources through both
paths. Each row checks that the two resolvers return the same value,
compared with equality.Semantic as updateResources does, and that a
workload rendered by the creation path is left untouched by
syncRuntimeSpec. The rows cover the nil/empty boundary on both sides
and claims.

Reverting either path alone to the wholesale replacement fails the
partial-overlay, added-key, empty-list and claims rows.

Signed-off-by: btxu-db <btxu-db@outlook.com>
The curvine suite covered create, bind, IO and scaling, but none of the
in-place resources update line (fluid-cloudnative#6165, fluid-cloudnative#6167, fluid-cloudnative#6173) ran against a real
cluster.

Give the worker template a full set of requirements, then patch only
limits.memory on the CacheRuntime. The AdvancedStatefulSet must take
the new value and keep the three keys the CacheRuntime did not name.
Wait for the update to roll out, in place or by recreation depending on
the cluster, and check that the worker pod carries the merged values
before the scaling case runs.

Signed-off-by: btxu-db <btxu-db@outlook.com>
Three consequences of the resources overlay that operators need to
know:

- Editing resources in a CacheRuntimeClass template now reaches every
  CacheRuntime using that class, on its next reconcile, for the keys it
  does not override. Removing all of the template's resources while the
  CacheRuntime sets none leaves the workload's values in place.
- After upgrading, a CacheRuntime that set only part of resources gets
  the template's other requirements back on the first reconcile, which
  updates the affected pods once.
- claims can only reference pod-level resourceClaims the template
  declares. Any other name now makes pod creation fail validation;
  earlier releases ignored a claims-only CacheRuntime.

List claims among the supported sub-fields, as the resolution order
already mentions them.

Signed-off-by: btxu-db <btxu-db@outlook.com>
The specs for a CacheRuntime that names only part of the template's
resources drove the worker alone. The master resolves its resources
through the same desiredComponentResources, so add the same case for
it: a full template, limits.memory raised on the CacheRuntime, and the
other three keys expected to survive the sync.

Generalise the worker-only workload helper to take the workload name so
both components share it.

Signed-off-by: btxu-db <btxu-db@outlook.com>

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

The merge can synthesize invalid request-and-limit combinations that prevent workloads from converging.

2 open findings
1 resolved since last review

🧠 Review effort: Balanced

Comment on lines +195 to +196
mergeResourceList(&merged.Limits, overlay.Limits)
mergeResourceList(&merged.Requests, overlay.Requests)
cheyang pushed a commit to cheyang/fluid that referenced this pull request Oct 11, 2026
… (delta c1c303e..e259d73)

Re-verified B1-B5 on head e259d73 (all FIXED) and the full engine suite
(292 vs 275 passed, identical pre-existing failure set). New probes:
D1 nil-removal semantics (contract), D2 requests-above-limits synthesis
(canary, open finding), D3 quota read-back boundary (contract).
.last-reviewed advanced to e259d73. Production code untouched.

Co-Authored-By: Claude Code <noreply@anthropic.com>
Signed-off-by: btxu-db <btxu-db@outlook.com>

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

Validation misses equality requirements for huge-page and extended resources, allowing invalid merged pod specifications.

3 open findings

🧠 Review effort: Balanced

Comment thread pkg/ddc/cache/engine/transform_common.go
cheyang pushed a commit to cheyang/fluid that referenced this pull request Oct 12, 2026
… resources

Kubernetes requires huge pages and extended resources to set a request
equal to their limit, and a limit whenever a request is set. A merged
pair such as a template pinning nvidia.com/gpu to 1 plus a CacheRuntime
raising only the limit to 2 passed validateResourceRequirements and was
only rejected once a Pod was created, while sync patched it onto the
workload. Validate those resources too, using a local mirror of
IsOvercommitAllowed since that helper package is not vendored.

Signed-off-by: btxu-db <btxu-db@outlook.com>

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

Newly added container claims can reach existing workloads without their pod-level declarations, causing replacement Pods to be rejected.

3 open findings
1 resolved since last review

🧠 Review effort: Balanced

Comment thread pkg/ddc/cache/engine/sync.go
cheyang pushed a commit to cheyang/fluid that referenced this pull request Oct 15, 2026
…bbea..3adc547): D7/D8 pin the F9 fix, E1 pins the new pre-existing claims wedge (F11), E2 refutes the empty-map clear claim

Production code untouched — the diff is this harness only.

Co-Authored-By: Claude Code <noreply@anthropic.com>

@cheyang cheyang left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Round 4 (497bbea -> 3adc547): the one ask from the last review landed, and it landed right. The single delta commit teaches validateResourceRequirements the API server's non-overcommittable rules — for hugepages-* and extended resources such as nvidia.com/gpu, a request must equal its limit, and a request needs a limit at all — via a local isOvercommitAllowed mirror (the upstream helper's package is genuinely not vendored, so the copy is justified). Both harnesses prove the flip independently: new contract tests are red on the previous head and green here — the sync refuses a merged gpu 1/2 pair, leaves the workload untouched, still moves replicas, emits a RuntimeResourcesConflict Warning event naming the key, and a second sync patches nothing — and the mirror matches k8s v1.29.15 line for line, including the upstream quirk that kubernetes.io/-prefixed qualified names stay overcommittable. The one apiserver rule deliberately left out (hugepages needing cpu or memory) is provably safe to leave out: the merge preserves the union of keys, so the cpu/memory accompanying hugepages in either input survives. The PR's own specs cover the validator table, the master creation path and the sync event, and the docs are updated in both languages. Both round-3 harnesses re-ran fully green on the new head, the engine suite shows no regression (312 passed vs 298, the 12 failures byte-identical and pre-existing), a test-merge with current master is clean, and every CI lane is green at the exact head — DCO included.

One new item, filed as minor and non-blocking (F11 — and not a Copilot-only flag: all three reviews converged on it, each side reproducing it independently): a CacheRuntimeClass edit that adds a pod-level resourceClaims entry and its matching container claim propagates the container claim into existing workloads through the merged desired resources, while nothing ever writes the workload's pod-level spec.resourceClaims — replacement Pods are then rejected by the API server and the rollout stalls with no event on the CacheRuntime. The same wedge exists on the merge base for the natural template shape, so the mechanism is pre-existing and out of this PR's strict scope; the PR only widens exposure for partial-override runtimes and claim-only templates. If it is worth closing, the cheap remedy is the guard pattern this PR already uses twice: check the merged claims against the workload's pod-level declarations, skip and emit a Warning event — or document the class-edit limitation.

There was no disagreement between the two reviewers this round; the one dispute on record is with Reviewer C's other carried thread (an explicit limits: {} "failing to clear" the workload) — it does not reproduce and is refuted by a contract passing on base, previous head and head, while its merged-validation thread is exactly what rounds 3-4 implemented.

With that, everything this pipeline asked for across four rounds on the code itself is done. Still outstanding before merge, unchanged: the maintainer ack of the broadened clear semantics (F1) — no human maintainer comment on the PR or #6165 since round 2; the cheyang review entries on the PR are this pipeline's own published summaries, not a personal decision.

Next round

[MUST] none — no blocker or major remains open.
[SHOULD] Maintainer ack of the broadened clear semantics (F1) before merge — the one non-nit item left, and it is the merge owner's call, not a code change.
[SHOULD] F11 at author's/maintainer's discretion: guard claims in validDesiredResources against the workload's pod-level declarations (skip + Warning event, the F6/F9 pattern), or document the class-edit limitation in both languages; invert E1 / flip the canary when taken.
[SHOULD] Nits, author's discretion: emit the RuntimeResourcesConflict reason on the creation-path rejection and add a client creation-rejection spec (F10, half-closed this round by the new master spec); a nil-Topology guard in syncRuntimeSpec (F7, pre-existing); a tiered-store row in the equivalence table (F8).
[Filed] none.

Non-blocking observations (2) — not part of this round's ask; fix now, follow up, or file an issue as you see fit
  • pkg/ddc/cache/engine/sync.go:267 — A CacheRuntimeClass edit adding a pod-level resourceClaims entry half-propagates: the container claim reach... [minor] — pre-existing, not introduced by this PR
  • pkg/ddc/cache/engine/transform_worker.go:47 — Creation-path conflict rejects with a generic event reason; client still lacks a creation-rejection spec (m... [nit]
Verified review delta
  • F9: fixed (initial-pr)
  • F11: open (preexisting)
  • F6: fixed (initial-pr)
  • F10: open (initial-pr)
  • F12: refuted (initial-pr)

Code: clear. CI: success; attribution: baseline. Required CI checks still apply.

CacheRuntime has not shipped in a release yet, so there is no earlier
behavior to upgrade from. Remove the upgrade note and the remark about
earlier releases ignoring claims, and keep the one fact the note added:
a template edit updates the master and worker Pods, recreating them
where the cluster cannot resize them in place.

Signed-off-by: btxu-db <btxu-db@outlook.com>
…icting resources

The sync path already names the conflicting keys in a
RuntimeResourcesConflict Warning event, but the creation path only
returned an error that surfaced under the generic setup failure reason.
Emit the same reason when the master, worker or client is rejected on
creation, and cover all three components, the client included.

Signed-off-by: btxu-db <btxu-db@outlook.com>
getRuntimeClass already rejects such a class, so no production caller
reaches the dereference; the guard keeps a direct caller from panicking
and, like the transform path, syncs no component.

Signed-off-by: btxu-db <btxu-db@outlook.com>
…ce table

The creation path adds the tiered store memory quota to the merged
resources and the sync path charges it back from the workload. Add a
Memory-medium emptyDir row and a process memory row, and have the
resolve check charge the quota the way syncRuntimeSpec does.

Signed-off-by: btxu-db <btxu-db@outlook.com>
Assert the Warning type alongside the reason, and that each rejected
creation emits the event once.

Signed-off-by: btxu-db <btxu-db@outlook.com>
…able charges

The rows compared the two paths against each other, so a quota that both
paths dropped would still agree. Pin the quota and the resulting memory
request and limit the creation path must render for each row.

Signed-off-by: btxu-db <btxu-db@outlook.com>

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔵 Needs a closer look

Resource-clearing semantics and class-wide workload rollouts warrant final human review.

3 open issues

Review effort: Balanced

cheyang pushed a commit to cheyang/fluid that referenced this pull request Oct 18, 2026
…c547..ce4f0c4): D9 pins the nil-topology guard (F7), D10 pins tiered-store quota agreement (F8), D11 pins the creation-path conflict event (F10)

@cheyang cheyang left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Round 5 (3adc547 -> ce4f0c4): the last three carried nits landed, and each is closed by proof rather than by reading the diff. The creation path now emits the specific RuntimeResourcesConflict Warning when it rejects a merged spec, for all three components — worker, master and client, the client gaining its first creation-rejection spec (F10): both harnesses flip red -> green, rejection-without-event on the previous head and on the merge base, error + exactly one event naming the conflict here. syncRuntimeSpec now guards a topology-less class instead of dereferencing it (F7): a recovered nil-pointer panic on base and the previous head, a clean no-op here with workloads untouched. And the creation/sync equivalence table renders tiered-store workloads with the charged quota pinned per row (F8), so a row can no longer pass with the quota silently dropped — honestly a coverage fix: the quota machinery predates this PR on the merge base, and the harness pin passes on both heads by design.

The docs drop the upgrade notes, and the premise holds under two independent verifications: the CacheRuntime API is in no release tag, absent from the v1.0.8 tree, and no release branch newer than release-1.0 exists — nothing released ships the feature, so there is no upgrade path to warn about. One trivial residual, new this round: the PR body still carries that upgrade note (F13, nit, at your discretion).

Everything earlier stays green: both majors (F6 request>limit refusal, F9 non-overcommittable must-equal) re-verified fixed at this head with the validator untouched by the delta; the full re-verify sweep is green except the one expected red; the engine suite shows no revision regression (321 passed vs 312, the 12 failures byte-identical and pre-existing); and every CI lane is green at the exact head — DCO included, e2e on all five Kubernetes versions.

There was no disagreement between the reviewers this round — every flip was independently reproduced on both harnesses; the only divergence was bookkeeping (the stale PR-body paragraph, folded into F2 by one reviewer and split out as F13 by the other; the split is adopted). Reviewer C (Copilot) reviewed this head and raised no inline findings; of its historical threads, one is refuted (the explicit limits: {} claim), one is exactly what rounds 3-4 implemented (merged-request validation), and one is the still-open F11.

F11 itself is unchanged: the pre-existing class-claims half-propagation wedge (canary still passing at head), still pre-existing on the merge base for its dominant shape, still minor and non-blocking — guard or document at your discretion.

Still outstanding before merge, unchanged after five rounds: the maintainer ack of the broadened clear semantics (F1) — the latest cheyang review entry is this pipeline's own round-4 summary, not a personal decision, and #6165's proposal still has no human reply. That is the merge owner's call; there is nothing further for a code round to ask of the author.

Next round

[MUST] none — no blocker or major remains open, and no new finding beyond a nit this round.
[SHOULD] Maintainer ack of the broadened clear semantics (F1) before merge — the one non-nit item left, and it is the merge owner's call, not a code change.
[SHOULD] F11 at author's/maintainer's discretion: guard claims in validDesiredResources against the workload's pod-level declarations (skip + Warning event, the F6/F9 pattern), or document the class-edit limitation in both languages; the E1/canary contract flips when taken.
[SHOULD] Cosmetic: drop the stale upgrade-note paragraph from the PR description (F13).
[Filed] none.

Non-blocking observations (1) — not part of this round's ask; fix now, follow up, or file an issue as you see fit
  • docs/en/samples/cacheruntime/cacheruntime_spec_update.md:1 — nit: the PR body still carries the upgrade-note paragraph the docs deliberately dropped this round [nit]
Verified review delta
  • F7: fixed (preexisting)
  • F8: fixed (initial-pr)
  • F10: fixed (initial-pr)
  • F13: open (initial-pr)

Code: clear. CI: success; attribution: baseline. Required CI checks still apply.

The sync patches container resources only. A CacheRuntimeClass edit that
adds a pod-level resourceClaims entry and the matching container claim
would carry the container claim into existing workloads without the
pod-level entry, and with DynamicResourceAllocation enabled the API server
would then reject every replacement Pod, stalling the rollout with nothing
on the CacheRuntime.

Leave out of the synced resources any claim the workload's pod spec does
not declare and its container does not already carry, emit a
RuntimeResourcesConflict Warning event naming it, and still sync the rest.
Skipping the whole resources instead would hold back a requests or limits
edit on clusters without DRA, where the API server ignores claims anyway;
keeping claims the container already carries avoids rolling a workload
whose Pods would not change. Document the limitation in both languages.

Signed-off-by: btxu-db <btxu-db@outlook.com>
@sonarqubecloud

Copy link
Copy Markdown

@cheyang

cheyang commented Oct 20, 2026

Copy link
Copy Markdown
Collaborator

Maintainer decision on the open semantics question (F1). This one is from me, not the review pipeline. Thanks @btxu-db for carrying this through five rounds; the code is in good shape.

Per-key overlay: agreed. The CacheRuntime expresses deltas on top of the CacheRuntimeClass template: requests/limits merge by resource name, claims by name. That is how transformComponentPodTemplate already layers labels, annotations and nodeSelector, and it is the fix for #6173.

"A key neither side declares is cleared": agreed. The three behaviour changes this brings (the CacheRuntime drops its last key, the template drops its last key, a value on the AdvancedStatefulSet that neither side declares) all come from the nil return added in #6165, which only applies when both sides are empty. One step away from that boundary, master already clears or reverts:

Case master this PR
CacheRuntime removes its last key (template empty) kept cleared
CacheRuntime removes one key, others remain cleared cleared
Value edited on the ASTS, both sides empty kept reverted
Value edited on the ASTS, either side non-empty reverted reverted

The "kept" rows are a side effect of that nil return, not a contract anyone should rely on. A resolved value that is a pure function of the two inputs is the right model for a declarative controller.

No upgrade concern. CacheRuntime hasn't shipped: it isn't in v1.0.8 or on release-1.0. Master builds may converge once, which is fine. Please drop the leftover upgrade paragraph from the PR description (F13).

One change before merge: please don't document live template propagation. Remove or neutralize:

  • in docs/{en,zh}/samples/cacheruntime/cacheruntime_spec_update.md: the "Edits to the template's resources reach existing instances" bullet, and the advice in the overridden-but-not-removed bullet to "change the CacheRuntimeClass template" to drop a requirement;
  • in the PR description: the matching "edits to the template's resources reach existing instances" line under Behaviour changes.

A neutral sentence is enough, e.g. "How CacheRuntimeClass edits affect existing CacheRuntimes is tracked in #6213; don't rely on them reaching existing instances."

Here's why. CacheRuntimeClass is cluster-scoped, the controller doesn't watch it, and every CacheRuntime is requeued every 90s by default. A single class edit would therefore resize or recreate the master and worker pods of every CacheRuntime using that class, across all namespaces, within about one requeue interval. Where in-place resize isn't available the pods are recreated, which means a cold cache for memory and emptyDir tiers. Also, only resources would follow the class: image, args, env, volumes and pod-level resourceClaims keep their creation-time values. F11 is exactly that mismatch.

So the plan is to pin the template when the components are created and keep this PR's per-key overlay on top of that pinned baseline. The proposal is in #6213. It is a follow-up to this PR and should land before v1.1.0, the first release with CacheRuntime. No code change is needed here: reading the live class on master is fine until then, because nothing has shipped. Once the baseline is pinned, the class-edit case of F11 goes away, because container claims and pod-level resourceClaims come from the same creation-time template. splitDeclaredClaims will then only need to check claims the CacheRuntime itself adds, so there is nothing more to do for F11 in this PR.

With the doc change and F13, this is good to merge from my side.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔵 Needs a closer look

Resource-clearing and class-wide update semantics can roll existing workloads and warrant human confirmation with cluster-level validation.

2 open issues
1 resolved since last review

Review effort: Balanced

@cheyang cheyang left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Round 6 (ce4f0c4f → a773dfa6): one commit, and it closes the last open risk with proof. The F11 class-claims wedge — a CacheRuntimeClass edit adding a pod-level resourceClaims entry plus the matching container claim, half-propagating to existing workloads and stalling their rollouts with no signal — is fixed by the exact guard shape round 5 proposed: splitDeclaredClaims splits the merged container claims by what the workload's pod spec declares (pod-level, or already carried by the container), and validDesiredResources drops the undeclared ones, emits one RuntimeResourcesConflict Warning naming them, and still syncs requests and limits, so a claim-only edit cannot hold back a limits edit on non-DRA clusters. Both harnesses prove it independently: one contract flips fail → pass (still-broken at the previous head, green here), and a second three-ref differential is red on the merge base (wholesale apply), red on the previous head (claim propagated, no warning), green at head (drop + named Warning + convergence), with pass-through pins confirming no over-drop of declared or already-carried claims. Full credit to Codex for self-disclosing that the round-4 canary could structurally never report a fix: it is retired and replaced by polarity-correct contracts, and no earlier conclusion rested on it. The full re-verify sweep is green on both harnesses with no exceptions; the engine suite shows no revision regression (329 passed vs 321, +8 new claim specs, the 12 failures byte-identical and pre-existing); and every CI lane is green at the exact head — DCO included, e2e on all five Kubernetes versions.

The process side moved too. The maintainer decision this PR has waited six rounds for has landed (F1 closed): the 2026-10-20 comment — a personal decision, not a pipeline artifact — agrees to the per-key overlay and to "a key neither side declares is cleared", and confirms there is no upgrade concern. The same comment records one change before merge, which is the round's one new finding and the only disagreement between the reviewers — a severity label, not a fact, since both confirm the finding, the evidence, and the gate. The en/zh docs and the PR description still advertise live CacheRuntimeClass template-edit propagation to existing instances (the "Edits to the template's resources reach existing instances" bullet, the "change the CacheRuntimeClass template" advice, and the matching Behaviour-changes line). The maintainer asks these be neutralized and pointed at #6213, which will pin the class template at creation — and the mechanism checks out under both reviewers' independent verification: nothing watches the cluster-scoped class, every CacheRuntime requeues on a 90-second default, only resources follows the class, and pod recreation means a cold cache. The documented behavior is true of the code today, so I am treating this as a documentation-policy gate rather than a code defect — but it is the merge owner's recorded pre-merge requirement, so it stays change-requesting until the edit lands. With it and the body cleanup below, the maintainer states the PR is good to merge from their side.

Reviewer C (Copilot) reviewed this head, marked its historical claims thread resolved, and raised no new inline findings; of its other threads, the limits: {} claim stays refuted and the merged-request-validation one is what rounds 3-4 already implemented.

Next round

[MUST] F14: neutralize the live-template-propagation passages — the "Edits to the template's resources reach existing instances" bullet (en:101, zh:97), the "change the CacheRuntimeClass template" advice (en:96-99, zh:94-96), and the matching PR-body Behaviour-changes line — pointing at #6213 instead (the maintainer's recorded 2026-10-20 pre-merge requirement).
[MUST] F13: drop the stale "Upgrade note." paragraph from the PR description and refresh the adjacent claims bullet, which now describes only the creation path (both named in the same maintainer comment).
[SHOULD] none further — all code findings are fixed and verified at head a773dfa6.
[Filed] #6213 (maintainer-filed): pin the CacheRuntimeClass template at creation; subsumes the class-edit case of F11 before the first CacheRuntime release.

Verified review delta
  • F14: open (initial-pr)
  • F11: fixed (preexisting)
  • F1: fixed (initial-pr)

Code: needs-work. CI: success; attribution: baseline. Required CI checks still apply.

unconstrained. To relax a limit, set the value you want explicitly; to drop a requirement
altogether, change the CacheRuntimeClass template, which is where the runtime's own requirements
are described.
- ⚠️ **Edits to the template's `resources` reach existing instances**: the CacheRuntimeClass template

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

F14 (new this round, raised independently by both reviewers; severity adjudicated by the synthesis — Codex major, Claude minor, both confirmed existence, content, attribution and the merge gate, and Claude explicitly consented to this finding occupying the blocking slot, so the dispute is the label, not the finding): at head a773dfa both language docs still carry the '⚠️ Edits to the template's resources reach existing instances' bullet (en:101, zh:97), the 'overridden but not removed' bullet still advises 'change the CacheRuntimeClass template' to drop a requirement (en:96-99, zh:94-96), and the PR description still lists 'edits to the template's resources reach existing instances' under Behaviour changes. The maintainer's recorded decision (cheyang, issue comment 2026-10-20T12:38:43Z, self-identified personal decision, not a pipeline artifact) gates merge on neutralizing exactly these passages — a neutral pointer to #6213 suffices ('How CacheRuntimeClass edits affect existing CacheRuntimes is tracked in #6213; don't rely on them reaching existing instances') — and states 'With the doc change and F13, this is good to merge from my side.' The rationale was independently re-verified by both reviewers: the controller registers no watch on CacheRuntimeClass, every CacheRuntime requeues on defaultRuntimeReconcileDuration = 90s (pkg/utils/crtl_utils.go:38), so one cluster-scoped class edit resizes or recreates the master/worker pods of every CacheRuntime using that class within about one interval (recreation = cold cache for memory/emptyDir tiers), while only resources follows the class — image, args, env, volumes and pod-level claims keep creation-time values (F11 was exactly that mismatch). #6213 (OPEN, maintainer-filed 2026-10-20) pins the template at creation, so the documented propagation semantic stops being true once it lands; advertising it in merged docs entrenches a contract the project intends to remove before the first release carrying CacheRuntime. The content is PR-introduced (absent at merge base e0fc4c1, grep count 0) and the round-6 commit predates the decision (committed 2026-10-19, decision 2026-10-20), so this is pending work, not author pushback and not a revision regression. The documented behavior is accurate against the code at head — a documentation-policy correction, not a code defect; the change-requesting weight rests on the merge owner's recorded pre-merge requirement, which both debaters verify and relay, and under which the required action is identical regardless of the severity label.

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

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[BUG]CacheRuntime: a partially specified resources silently drops the rest of the container's resource requirements

4 participants