Skip to content

k8s manifests: multi-document files read as their first document; generated-file truncation can hide detection #258

Description

@nikolay-e

Two findings from the 2026-08-30 QA review of the #226 rewrite, both real, neither fixed in that pass because they are behaviour changes rather than defects in the fix.

1. A multi-document manifest is read as its first document only

build_manifest_views produces one ManifestView per FILE, and extract_resource_info takes the first ^kind: and the first metadata:\n name: of the whole reconstructed text. So a bundle.yaml holding ConfigMap + Deployment + Service is indexed as a ConfigMap; the Deployment is never a workload for selector matching, and references to that Service by name resolve to nothing.

Worse in the label path: extract_labels merges every labels: block in the file into one map, last-wins. A file with two Deployments (app: web, app: api) keeps only app: api, so a Service selecting app: web gets no edge.

Not a regression — before the fix this builder emitted nothing at all for any split manifest — but it is a correctness ceiling that neither the code nor its tests mention. Close condition: a corpus case with a ----separated bundle whose second document is the selector target, passing.

2. The generated-file reduction can delete the two lines detection needs

fragmentation.rs truncates an unchanged file whose header says do not edit / generated by to max_generated_fragments = 5, sorted by line count — and apiVersion: / kind: are one-line fragments, so they go first. The reconstructed text then has no kind:, is_kubernetes_manifest is false, and the whole file drops out of views.

This matters precisely for rendered/committed manifests, which is where cross-file k8s edges live. The old per-fragment path was less sensitive because it only needed one qualifying fragment; whole-file reassembly needs the file to survive intact. Close condition: a case with a # Generated by kustomize header whose Deployment is still pulled by its Service.

Both are Q-class (they change edges), so they wait for the v3 cycle's freeze boundary — see #256.

Activity

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions