Two placement defects found while reviewing #291. Both are reachable on main today, both are small,
and neither needs the layout model to land first. Findings and the fix shape:
docs/design/placement-visibility-and-declared-defaults.md
(findings F3, F4, F10).
1. A declared path into a kustomize subdirectory produces a file nothing renders
Symptom. One byType line is enough:
placement:
byType:
v1/configmaps: "configmaps/{name}.yaml"
pointed at a folder governed by a kustomization.yaml at its root. The file is committed to
configmaps/foo.yaml, no kustomization lists it, and kubectl apply -k never renders it. The mirror
contains a document that is not part of the folder it claims to be part of.
Cause. governingKustomization uses an own-directory check plus a write-scope special case, so a
declared path is registered with a kustomization only when render-root scoping happens to be in force.
The two cases differ by something the user cannot see.
Fix. Walk up to the nearest kustomization inside the write jail, so a byType or default path
into a subdirectory joins that root's resources: list. After the fix the two cases stop differing.
Note that #293 makes this class of bug unstatable rather than fixed, by registering the file with the
governing kustomization whatever chose the path. This issue is the fix for the model we have now; it
should not wait for the wave.
2. IdentityCompletePlacementTemplate demands {version}, which contradicts the versionless path
IdentityCompletePlacementTemplate(tmpl, false) requires {groupPath}, {version} and
{resource}. The built-in canonical path is deliberately versionless, because two versions of one
group/resource are the same object — which is exactly why the version segment was dropped.
Consequences:
- a template carrying scope, group, resource and name cannot collide two distinct identities, with or
without a version, so the requirement is wrong on its own terms;
- it is what makes any future spec-level default fail our own validation gate: the canonical shape we
would default to is judged not identity-complete, and every GitTarget that did not also declare an
identity-complete byType["v1/secrets"] entry would go Validated=False.
Fix. Drop the {version} requirement for a non-narrowed template, with a test asserting the
versionless canonical shape is accepted.
Acceptance
Two placement defects found while reviewing #291. Both are reachable on
maintoday, both are small,and neither needs the layout model to land first. Findings and the fix shape:
docs/design/placement-visibility-and-declared-defaults.md(findings F3, F4, F10).
1. A declared path into a kustomize subdirectory produces a file nothing renders
Symptom. One
byTypeline is enough:pointed at a folder governed by a
kustomization.yamlat its root. The file is committed toconfigmaps/foo.yaml, no kustomization lists it, andkubectl apply -knever renders it. The mirrorcontains a document that is not part of the folder it claims to be part of.
Cause.
governingKustomizationuses an own-directory check plus a write-scope special case, so adeclared path is registered with a kustomization only when render-root scoping happens to be in force.
The two cases differ by something the user cannot see.
Fix. Walk up to the nearest kustomization inside the write jail, so a
byTypeordefaultpathinto a subdirectory joins that root's
resources:list. After the fix the two cases stop differing.Note that #293 makes this class of bug unstatable rather than fixed, by registering the file with the
governing kustomization whatever chose the path. This issue is the fix for the model we have now; it
should not wait for the wave.
2.
IdentityCompletePlacementTemplatedemands{version}, which contradicts the versionless pathIdentityCompletePlacementTemplate(tmpl, false)requires{groupPath},{version}and{resource}. The built-in canonical path is deliberately versionless, because two versions of onegroup/resource are the same object — which is exactly why the version segment was dropped.
Consequences:
without a version, so the requirement is wrong on its own terms;
would default to is judged not identity-complete, and every GitTarget that did not also declare an
identity-complete
byType["v1/secrets"]entry would goValidated=False.Fix. Drop the
{version}requirement for a non-narrowed template, with a test asserting theversionless canonical shape is accepted.
Acceptance
byTypepath into a subdirectory of a kustomize folder is registered with the root thatgoverns it, with a test that fails before the change.
placement_kustomization_entries_totalno longer counts these asfailed(afailedvalue isa file committed outside every render, so this is also the metric's own regression test).
IdentityCompletePlacementTemplateaccepts the versionless canonical shape; the Secret-safetygate still rejects what it should.