Repository navigation
feat(cluster): stacks data list shows data the stack does not own (ankra-0xsdd.114) - #432
Conversation
…kra-0xsdd.114) The platform's stack data inventory now lists as assets only what one of the stack's members owns (cluster#3966), tags each asset with its attribution, and reports data the namespace sweep found that no member owns under unattributed_assets - never captured or restored as the stack's. The CLI printed only assets, so e.g. the platform database in a shared namespace silently vanished from `ankra cluster stacks data list cadence`. The table now has an "Owned via" column (the owning member, or a namespace only this stack uses), a "Not owned by this stack (unattributed)" section lists kind/namespace/name/size/Helm release, the help says unattributed data is never captured or restored, and -o json/yaml carry attribution and unattributed_assets. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Ankra AI reviewVerdict: looks good. The change cleanly separates owned assets from unattributed ones in both table and structured output, handles the empty-inventory case, and treats a missing attribution field from older platforms as unknown rather than guessing. Tests cover the new section, the empty case, help text, and JSON round-trip. No correctness or security issues found in the diff. Reviewed commit 5300bba. This review is read-only and advisory. |
| out := cmd.OutOrStdout() | ||
| if len(inventory.Assets) == 0 { | ||
| _, _ = fmt.Fprintf(out, "Stack '%s' holds no data a backup would carry.\n", stackName) | ||
| renderUnattributedDataAssets(out, inventory.UnattributedAssets) |
There was a problem hiding this comment.
[medium] Empty unattributed list may conflate 'sweep found nothing' with 'sweep never ran'
If the platform's namespace sweep that produces UnattributedAssets is unavailable or fails (the command's own help says the live read can come back unavailable), an empty or absent unattributed_assets list is indistinguishable from a sweep that ran and found nothing, so the command would silently omit the section and present an unknown as a negative answer. The diff does not show whether StackDataInventory carries a sweep/scan status for the unattributed side (CustomResourceScan appears to cover only the CR scan) or whether the unavailable path is handled before this point; if it is not, surface the sweep state explicitly rather than relying on len(assets) == 0.
Ankra AI review. Read-only and advisory.
There was a problem hiding this comment.
Partly valid; fixed the part that applies, in the next commit.
There is no separate sweep that can fail on its own. In cluster go/internal/usecase/importedread/stackdatainventory.go, unattributed_assets comes from the same pass that builds assets (partitionByMember over one asset list, which reads the synced k8s_resources rows). If that read fails, the endpoint returns an error, and the CLI exits non-zero through backupLaneError. It never renders an empty list in that case. The only partial lane is the live operator read, reported as custom_resource_scan, and the CLI already prints a stderr warning when it is unavailable.
That warning was still incomplete, though. Without the live read, a database's ownership cannot be proven, so the platform lists it under unattributed_assets rather than dropping it. The warning now says such a database may be "listed as not owned by this stack because its ownership could not be read", and TestStackDataListWarnsWhenTheLiveScanDidNotRun asserts it.
| Member *StackDataAssetMember `json:"member,omitempty" yaml:"member,omitempty"` | ||
| HelmRelease string `json:"helm_release,omitempty" yaml:"helm_release,omitempty"` | ||
| Status string `json:"status,omitempty" yaml:"status,omitempty"` | ||
| Attribution string `json:"attribution" yaml:"attribution"` |
There was a problem hiding this comment.
[low] New JSON fields lack omitempty, changing wire shape for old platforms
Attribution is tagged json:"attribution" without omitempty, so any code that marshals a StackDataAsset (e.g. tests or passthrough output) now always emits an empty attribution string, and UnattributedAssets likewise always serializes as null when unset. Harmless for decoding, but adding omitempty would keep the structured output stable against platforms that predate these fields.
Ankra AI review. Read-only and advisory.
There was a problem hiding this comment.
Intentional, not changed. These tags mirror the server's wire shape: cluster StackDataAsset.Attribution is json:"attribution" and StackDataInventory.UnattributedAssets is json:"unattributed_assets", both without omitempty, and the server always sends the list ([] when empty).
-o json re-marshals this struct. With omitempty, an empty [] from the current platform would disappear from the CLI's output, so jq '.unattributed_assets[]' would fail with "Cannot iterate over null" exactly when nothing is unattributed. Keeping the key always present matches the platform for every current response. Only a platform that predates cluster#3966 gives null and "", and cluster#3966 is already live in production.
…k-data-unattributed # Conflicts: # CHANGELOG.md
… be the stack's (ankra-0xsdd.114) Without the live database-operator read a database's ownership cannot be proven, so the platform lists it as unattributed. The stderr warning now says so instead of only "may be missing from this list". Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
What & why
cluster#3966 (merged, live) changed the stack data inventory that
ankra cluster stacks data listreads:assetsnow holds only what one of the stack's members owns, each asset carries anattribution(member,exclusive_namespace, orunattributed), and a new top-levelunattributed_assetslist holds what the namespace sweep found that no member owns. That data is never captured or restored as the stack's. The CLI printed onlyassets, so data in a shared namespace (for example the 1.6 TiB platform database in nsplatformfor stackcadence) silently dropped out of the list, and-o jsondropped both new fields because the client type did not have them.internal/client/stack_data_assets.go:StackDataAsset.Attribution,StackDataInventory.UnattributedAssets, and attribution constants. The wire shape mirrors the server's, so-o json|yamlcarry both.cmd/cluster_stacks_data.go: a new "Owned via" column (member addon/<name>ornamespace only this stack uses,-from a platform that sends no attribution). A "Not owned by this stack (unattributed)" section lists kind, namespace, name, size and Helm release, and says the data is never captured or restored. The section also prints when the stack owns nothing. The help explains attribution and says unattributed data is never captured or restored, and that the total does not count it.CHANGELOG.md: Unreleased entry.Bead: ankra-0xsdd.114
Test plan
go test ./cmd -run StackDataandgo test ./internal/client -run StackData: new tests for the attribution column, the unattributed section (contents, kept out of the owned table, absent when empty), the empty-assets-with-unattributed case, the help text, and-o jsoncarryingattributionandunattributed_assets.origin/masterrenderer, 4 of the new or extended tests fail.go test ./...andgolangci-lint run ./...).Docs checklist
tools/gendocs); ensureShort/Long/Exampleon new commands are written for docs readers🤖 Generated with Claude Code