[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill:01M6CBKBKAEPMHPNC8NJTREJ1R":3,"skill-same:01M6CBKBKAEPMHPNC8NJTREJ1R":82},{"skillNo":4,"name":5,"nameZh":6,"description":7,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":16,"categories":17,"keywords":18,"publishedAt":51,"linkOnly":52,"markdownContent":53,"markdownBody":54,"frontMatter":55,"refName":58,"commitSha":59,"skillDirectory":60,"forksCount":61,"repositoryHtmlUrl":62,"repositoryHomepageUrl":63,"ownerHtmlUrl":64,"ownerBlogUrl":65,"ownerDescription":66,"updatedAt":67,"install":68,"resources":81},"01M6CBKBKAEPMHPNC8NJTREJ1R","observe-confighub-managed",null,"Use when the user wants to observe CONFIGHUB-managed resources specifically — resources where the desired state lives in a ConfigHub Unit, delivered through Argo or Flux. Natural phrasing: \"is this a ConfigHub unit?\", \"which ConfigHub Unit \u002F Space produced this?\", \"show me ConfigHub-delivered-via-Argo resources\", \"what does `confighub.com\u002FUnitSlug` mean?\", \"is this delivered via Argo OCI or Flux Kustomize?\", \"trace this back to the ConfigHub revision\". Load when the user is specifically asking about ConfigHub-as-source-of-truth. Do NOT load for: vanilla Argo without ConfigHub (use observe-argocd), vanilla Flux (use observe-flux), generic ownership (use scout-observe), authoring ConfigHub units (use cub skills, not cub-scout).","confighub\u002Fcub-scout","confighub","https:\u002F\u002Favatars.githubusercontent.com\u002Fu\u002F206140369?v=4","01M6CBJBWD33AFNG4VXMJHSRXD","ConfigHub Inc","01M6CBJC0K0F8CJVFWGRSR0KYC",14,"MIT","https:\u002F\u002Fgithub.com\u002Fconfighub\u002Fcub-scout\u002Fblob\u002Fmain\u002Fskills\u002Fobserve-confighub-managed\u002FSKILL.md",[],[19,20,9,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50],"observe","managed","observe confighub managed","me","cub scout","scout compare","show","back","drift","when","map","get","impact","resources","unit","which","oci","use","view","list","kustomize","argocd","changeset","history","explain","Bash","show me","state","doctor","release","status","auth","2026-11-10 10:12:30",false,"---\nname: observe-confighub-managed\ndescription: 'Use when the user wants to observe CONFIGHUB-managed resources specifically — resources where the desired state lives in a ConfigHub Unit, delivered through Argo or Flux. Natural phrasing: \"is this a ConfigHub unit?\", \"which ConfigHub Unit \u002F Space produced this?\", \"show me ConfigHub-delivered-via-Argo resources\", \"what does `confighub.com\u002FUnitSlug` mean?\", \"is this delivered via Argo OCI or Flux Kustomize?\", \"trace this back to the ConfigHub revision\". Load when the user is specifically asking about ConfigHub-as-source-of-truth. Do NOT load for: vanilla Argo without ConfigHub (use observe-argocd), vanilla Flux (use observe-flux), generic ownership (use scout-observe), authoring ConfigHub units (use cub skills, not cub-scout).'\nphase: cross-cutting\nallowed-tools: Bash(.\u002Fcub-scout doctor *) Bash(cub-scout doctor *) Bash(cub scout doctor *) Bash(.\u002Fcub-scout explain *) Bash(cub-scout explain *) Bash(cub scout explain *) Bash(.\u002Fcub-scout trace *) Bash(cub-scout trace *) Bash(cub scout trace *) Bash(.\u002Fcub-scout map list *) Bash(.\u002Fcub-scout map workloads *) Bash(.\u002Fcub-scout map orphans *) Bash(cub-scout map list *) Bash(cub-scout map workloads *) Bash(cub-scout map orphans *) Bash(cub scout map list *) Bash(cub scout map workloads *) Bash(cub scout map orphans *) Bash(.\u002Fcub-scout compare three-way *) Bash(cub-scout compare three-way *) Bash(cub scout compare three-way *) Bash(.\u002Fcub-scout compare drift *) Bash(cub-scout compare drift *) Bash(cub scout compare drift *) Bash(.\u002Fcub-scout compare source-truth *) Bash(cub-scout compare source-truth *) Bash(cub scout compare source-truth *) Bash(.\u002Fcub-scout history *) Bash(cub-scout history *) Bash(cub scout history *) Bash(.\u002Fcub-scout impact *) Bash(cub-scout impact *) Bash(cub scout impact *) Bash(kubectl get *) Bash(kubectl describe *) Bash(kubectl get --show-managed-fields *) Bash(cub space list *) Bash(cub unit get *) Bash(cub unit list *) Bash(cub link get *) Bash(cub link list *) Bash(cub view get *) Bash(cub view list *) Bash(cub unit-event list *) Bash(cub resource list *) Bash(cub release list *) Bash(cub changeset list *) Bash(cub auth status)\n---\n\n# observe-confighub-managed\n\nThe controller-specific observer skill for **ConfigHub-managed** resources — workloads whose desired state lives in a ConfigHub Unit and gets delivered through Argo (typically via OCI artifact) or Flux (Kustomization \u002F OCIRepository). This skill is the bridge between cub-scout's \"who owns the live resource?\" question and ConfigHub's \"where does the intent live?\" answer.\n\nVerified against `pkg\u002Fagent\u002Fownership.go` `detectConfigHubOwnership` and `pkg\u002Fagent\u002Fmanager_strings.go` `controllerManagersForOwner(OwnerConfigHub, ...)`.\n\n## When to use\n\n- \"Is this a ConfigHub Unit?\"\n- \"Which ConfigHub Unit \u002F Space produced this?\"\n- \"Show me ConfigHub-delivered-via-Argo resources\"\n- \"What does the `confighub.com\u002FUnitSlug` label mean?\"\n- \"Is this resource delivered via ConfigHub-OCI-Argo or ConfigHub-OCI-Flux?\"\n- \"Trace this back to the ConfigHub revision\"\n- \"Why does cub-scout classify this as OwnerConfigHub when Argo labels are also present?\"\n\n## Do not load for\n\n- Vanilla Argo without ConfigHub — [`observe-argocd`](..\u002Fobserve-argocd\u002FSKILL.md)\n- Vanilla Flux — [`observe-flux`](..\u002Fobserve-flux\u002FSKILL.md)\n- Generic ownership (\"who owns this?\") — [`scout-observe`](..\u002Fscout-observe\u002FSKILL.md)\n- Authoring ConfigHub Units \u002F Spaces \u002F Targets — that's `cub`, not cub-scout. Route to [`confighub\u002Fconfighub-skills`](https:\u002F\u002Fgithub.com\u002Fconfighub\u002Fconfighub-skills).\n- Comparing ConfigHub intent to live state — [`scout-compare`](..\u002Fscout-compare\u002FSKILL.md) (`compare three-way`, `compare source-truth`)\n\n## Detection signals (in `detectConfigHubOwnership`)\n\ncub-scout classifies a resource as ConfigHub-owned when EITHER signal is present:\n\n| Signal | Source | SubType | Confidence | Notes |\n|--------|--------|---------|-----------|-------|\n| `confighub.com\u002FUnitSlug` label | label | `unit` | high | Primary signal. `Namespace` is populated from `confighub.com\u002FSpaceName` (annotation preferred, label fallback). |\n| `confighub.com\u002FUnitSlug` annotation | annotation | `unit` | high | Fallback for resources where the unit slug lives in annotations. `Namespace` from `confighub.com\u002FSpaceName` annotation. |\n\nResulting `Ownership`: `Type=confighub`, `SubType=unit`, `Name=\u003Cunit-slug>`, `Namespace=\u003Cspace-name>`.\n\n## Why ConfigHub priority is BEFORE Argo \u002F Flux\n\nThe ownership detector runs **ConfigHub detection BEFORE Argo and Flux**. A resource delivered through `Argo CD reading a ConfigHub-rendered OCI bundle` has BOTH `confighub.com\u002FUnitSlug` AND `argocd.argoproj.io\u002Finstance` labels. Without the priority order, the resource would classify as `OwnerArgo` and the \"delivered by ConfigHub\" fact would be lost.\n\nThe detector ordering reflects the architectural triad's authority model:\n- ConfigHub is **authority** (where the intent lives — runs first)\n- Argo \u002F Flux are **delivery** (how the intent reaches the cluster — run second)\n- The live resource is **runtime** (what actually got applied)\n\nA ConfigHub-managed resource still gets full Argo\u002FFlux *attribution* even though it classifies as `OwnerConfigHub`. The attribution layer's controller co-signal accepts both `argocd-controller` and `kustomize-controller` \u002F `helm-controller` as valid writers for ConfigHub-owned resources — see \"Controller co-signals\" below.\n\n## Manager strings (writers in `metadata.managedFields`)\n\n`controllerManagersForOwner(OwnerConfigHub, ...)` returns FOUR matchers — the union of Argo and Flux core writers, because both delivery surfaces are valid for ConfigHub:\n\n| Manager | Source | Delivery path |\n|---------|--------|--------------|\n| `argocd-controller` | Argo CD application-controller SSA | ConfigHub → OCI → Argo CD → cluster |\n| `kubectl-client-side-apply` | Argo CD CSA migration default | Same path; Argo writes via CSA fallback |\n| `kustomize-controller` | Flux kustomize-controller | ConfigHub → OCI\u002FGit → Flux Kustomization → cluster |\n| `helm-controller` | Flux helm-controller | ConfigHub → OCI → Flux HelmRelease → cluster |\n\nAny of these as a writer is `controller-drift` (a controller reconciled the ConfigHub intent). A `kubectl-*` writer on a ConfigHub-owned resource is `manual-edit` — someone bypassed both ConfigHub AND the delivery controller.\n\n## Delivery path disambiguation\n\ncub-scout doesn't classify the *delivery* path in ownership detection — it just records the unit slug. To find out *how* a ConfigHub Unit got to the cluster, walk the labels:\n\n| If you also see... | The delivery path is... |\n|-------------------|------------------------|\n| `argocd.argoproj.io\u002Finstance` | ConfigHub-via-Argo (typically OCI) |\n| `kustomize.toolkit.fluxcd.io\u002Fname` | ConfigHub-via-Flux Kustomization |\n| `helm.toolkit.fluxcd.io\u002Fname` | ConfigHub-via-Flux HelmRelease |\n| Neither | Either a direct `cub` apply or an unusual delivery path; check `cub unit get \u003Cslug>` for the target |\n\nThe `compare source-truth --strategy \u003Cname>` verbs cover the four ConfigHub-aware strategies explicitly:\n- `confighub-oci-argo` — ConfigHub authors a Unit, renders to OCI, Argo CD reads OCI, applies to cluster\n- `confighub-oci-flux` — Same authoring chain, Flux is the deliverer\n- (helm \u002F git strategies aren't ConfigHub-authoritative; they describe vanilla Argo \u002F Flux)\n\n## Connected-mode evidence enrichment\n\nWhen cub-scout is run **connected** (`cub auth login`), additional ConfigHub-side evidence is layered onto the resource:\n\n- `confighubUrl` — the ConfigHub GUI deep-link to the unit's revision\n- `incomingBindings[]` — the upstream units feeding this unit via ConfigHub Links (#438)\n- per-field `bindingSource` — which Link supplies a specific field's value (#439)\n- `compare three-way` shows the full DRY (ConfigHub) \u002F WET (rendered) \u002F LIVE (cluster) trio\n- `compare source-truth --strategy confighub-oci-{argo,flux}` runs the strategy-typed verdict over all three surfaces\n\nStandalone-mode cub-scout still classifies as `OwnerConfigHub` (the label is on the live resource), but the connected-mode evidence isn't available. Receipts record this as `OmissionConfigHubUnitSubject`.\n\n## Worked example\n\n```bash\n$ kubectl get deploy api -n prod -o yaml | yq '.metadata.labels, .metadata.annotations, .metadata.managedFields[].manager'\nlabels:\n  confighub.com\u002FUnitSlug: payments-api\n  argocd.argoproj.io\u002Finstance: payments-app\n  app: api\nannotations:\n  confighub.com\u002FSpaceName: payments\n  argocd.argoproj.io\u002Ftracking-id: \"payments-app:apps\u002FDeployment:prod\u002Fapi\"\nmanagers:\n  - argocd-controller\n  - kubectl-edit                                          # uh oh\n```\n\ncub-scout reads this as:\n\n```\n$ cub-scout explain deploy\u002Fapi -n prod\nResource: Deployment\u002Fapi in prod\n  Owner:    ConfigHub unit \"payments-api\" in space \"payments\" (label:confighub.com\u002FUnitSlug)\n  Delivered via: Argo CD application \"payments-app\" (label:argocd.argoproj.io\u002Finstance)\n  Drift:    Detected\n  Mutation cause: manual-edit (manager: kubectl-edit; controller co-signal: argocd-controller)\n  ConfigHub URL: https:\u002F\u002Fhub.confighub.com\u002Fp\u002Fpayments\u002Fu\u002Fpayments-api    (connected mode)\n```\n\nThe classifier correctly identifies BOTH the source of truth (ConfigHub Unit) and the delivery path (Argo). The mutation cause is `manual-edit` despite the controller co-signal — that's the attribution layer's job.\n\n## Edge cases\n\n- **`confighub.com\u002FUnitSlug` annotation without the label**: Some resources only get the annotation. cub-scout's second branch in `detectConfigHubOwnership` catches this. `SpaceName` is still read from annotations (not labels) for consistency.\n- **ConfigHub-managed without a delivery controller**: A `cub apply` directly to the cluster (no Argo \u002F Flux in the middle) leaves only `confighub.com\u002FUnitSlug` on the resource. Ownership classifies as `OwnerConfigHub`; the controller writer is... whatever wrote it (often a `kubectl-*` form), which means `cause=manual-edit` even though the user intended a controlled apply. This is a known artifact of the `cub apply` path; #410\u002F#428 triad work is the long-term fix.\n- **ConfigHub via Helm (not Flux helm-controller)**: When ConfigHub renders to a Helm chart that's then handed to Argo's Helm renderer, the resource has `confighub.com\u002FUnitSlug` + `argocd.argoproj.io\u002Finstance` + `app.kubernetes.io\u002Fmanaged-by: Helm`. Detection priority: ConfigHub wins; controller co-signal recognizes `argocd-controller`. The Helm labels are an artifact of the chart, not evidence of a Helm-specific delivery.\n- **`OwnerConfigHub` with `cause=unknown`**: Older clusters that stripped `managedFields` produce this — the unit slug is there but cub-scout can't tell *who* wrote the live state. The attribution layer emits `cause=unknown` with an `OmissionManagedFields` entry rather than guessing.\n\n## References\n\n- Code: `pkg\u002Fagent\u002Fownership.go` `detectConfigHubOwnership`, `pkg\u002Fagent\u002Fmanager_strings.go` `controllerManagersForOwner(OwnerConfigHub, ...)`\n- Upstream: ConfigHub label spec — `confighub.com\u002FUnitSlug`, `confighub.com\u002FSpaceName`, `confighub.com\u002FSpaceID`, `confighub.com\u002FRevisionNum`\n- Related skills:\n  - [`scout-observe`](..\u002Fscout-observe\u002FSKILL.md) — the umbrella ownership detector\n  - [`scout-attribute`](..\u002Fscout-attribute\u002FSKILL.md) — per-field attribution; recognizes ConfigHub-via-Argo and ConfigHub-via-Flux controller co-signals\n  - [`scout-compare`](..\u002Fscout-compare\u002FSKILL.md) — `compare three-way` and `compare source-truth` use ConfigHub as the DRY layer\n  - [`scout-govern`](..\u002Fscout-govern\u002FSKILL.md) — `history`, `impact`, `views resolve` are ConfigHub-aware\n  - [`scout-verify`](..\u002Fscout-verify\u002FSKILL.md) — receipts add a `confighub-unit:\u002F\u002F` subject in connected mode\n  - [`observe-argocd`](..\u002Fobserve-argocd\u002FSKILL.md), [`observe-flux`](..\u002Fobserve-flux\u002FSKILL.md) — the delivery paths\n- Examples: [`examples\u002Fargo-import-confighub-demo\u002F`](..\u002F..\u002Fexamples\u002Fargo-import-confighub-demo\u002F), [`examples\u002Fflux-import-confighub-demo\u002F`](..\u002F..\u002Fexamples\u002Fflux-import-confighub-demo\u002F), [`examples\u002Fconnect-and-compare\u002F`](..\u002F..\u002Fexamples\u002Fconnect-and-compare\u002F)\n\n## Constraints\n\n- This skill is read-only. ConfigHub Unit mutation, space creation, target binding, etc. are all `cub` operations and out of allowed-tools.\n- ConfigHub detection priority is INTENTIONAL — a ConfigHub-managed resource classifies as `OwnerConfigHub` even when Argo \u002F Flux labels are also present. Don't reverse the order.\n- Connected-mode evidence enrichment requires `cub auth login`. Standalone-mode users get correct ownership classification but no `confighubUrl`, no `incomingBindings`, no DRY\u002FWET\u002FLIVE compare. Surface this as an omission, not silent missing data.\n","# observe-confighub-managed\n\nThe controller-specific observer skill for **ConfigHub-managed** resources — workloads whose desired state lives in a ConfigHub Unit and gets delivered through Argo (typically via OCI artifact) or Flux (Kustomization \u002F OCIRepository). This skill is the bridge between cub-scout's \"who owns the live resource?\" question and ConfigHub's \"where does the intent live?\" answer.\n\nVerified against `pkg\u002Fagent\u002Fownership.go` `detectConfigHubOwnership` and `pkg\u002Fagent\u002Fmanager_strings.go` `controllerManagersForOwner(OwnerConfigHub, ...)`.\n\n## When to use\n\n- \"Is this a ConfigHub Unit?\"\n- \"Which ConfigHub Unit \u002F Space produced this?\"\n- \"Show me ConfigHub-delivered-via-Argo resources\"\n- \"What does the `confighub.com\u002FUnitSlug` label mean?\"\n- \"Is this resource delivered via ConfigHub-OCI-Argo or ConfigHub-OCI-Flux?\"\n- \"Trace this back to the ConfigHub revision\"\n- \"Why does cub-scout classify this as OwnerConfigHub when Argo labels are also present?\"\n\n## Do not load for\n\n- Vanilla Argo without ConfigHub — [`observe-argocd`](..\u002Fobserve-argocd\u002FSKILL.md)\n- Vanilla Flux — [`observe-flux`](..\u002Fobserve-flux\u002FSKILL.md)\n- Generic ownership (\"who owns this?\") — [`scout-observe`](..\u002Fscout-observe\u002FSKILL.md)\n- Authoring ConfigHub Units \u002F Spaces \u002F Targets — that's `cub`, not cub-scout. Route to [`confighub\u002Fconfighub-skills`](https:\u002F\u002Fgithub.com\u002Fconfighub\u002Fconfighub-skills).\n- Comparing ConfigHub intent to live state — [`scout-compare`](..\u002Fscout-compare\u002FSKILL.md) (`compare three-way`, `compare source-truth`)\n\n## Detection signals (in `detectConfigHubOwnership`)\n\ncub-scout classifies a resource as ConfigHub-owned when EITHER signal is present:\n\n| Signal | Source | SubType | Confidence | Notes |\n|--------|--------|---------|-----------|-------|\n| `confighub.com\u002FUnitSlug` label | label | `unit` | high | Primary signal. `Namespace` is populated from `confighub.com\u002FSpaceName` (annotation preferred, label fallback). |\n| `confighub.com\u002FUnitSlug` annotation | annotation | `unit` | high | Fallback for resources where the unit slug lives in annotations. `Namespace` from `confighub.com\u002FSpaceName` annotation. |\n\nResulting `Ownership`: `Type=confighub`, `SubType=unit`, `Name=\u003Cunit-slug>`, `Namespace=\u003Cspace-name>`.\n\n## Why ConfigHub priority is BEFORE Argo \u002F Flux\n\nThe ownership detector runs **ConfigHub detection BEFORE Argo and Flux**. A resource delivered through `Argo CD reading a ConfigHub-rendered OCI bundle` has BOTH `confighub.com\u002FUnitSlug` AND `argocd.argoproj.io\u002Finstance` labels. Without the priority order, the resource would classify as `OwnerArgo` and the \"delivered by ConfigHub\" fact would be lost.\n\nThe detector ordering reflects the architectural triad's authority model:\n- ConfigHub is **authority** (where the intent lives — runs first)\n- Argo \u002F Flux are **delivery** (how the intent reaches the cluster — run second)\n- The live resource is **runtime** (what actually got applied)\n\nA ConfigHub-managed resource still gets full Argo\u002FFlux *attribution* even though it classifies as `OwnerConfigHub`. The attribution layer's controller co-signal accepts both `argocd-controller` and `kustomize-controller` \u002F `helm-controller` as valid writers for ConfigHub-owned resources — see \"Controller co-signals\" below.\n\n## Manager strings (writers in `metadata.managedFields`)\n\n`controllerManagersForOwner(OwnerConfigHub, ...)` returns FOUR matchers — the union of Argo and Flux core writers, because both delivery surfaces are valid for ConfigHub:\n\n| Manager | Source | Delivery path |\n|---------|--------|--------------|\n| `argocd-controller` | Argo CD application-controller SSA | ConfigHub → OCI → Argo CD → cluster |\n| `kubectl-client-side-apply` | Argo CD CSA migration default | Same path; Argo writes via CSA fallback |\n| `kustomize-controller` | Flux kustomize-controller | ConfigHub → OCI\u002FGit → Flux Kustomization → cluster |\n| `helm-controller` | Flux helm-controller | ConfigHub → OCI → Flux HelmRelease → cluster |\n\nAny of these as a writer is `controller-drift` (a controller reconciled the ConfigHub intent). A `kubectl-*` writer on a ConfigHub-owned resource is `manual-edit` — someone bypassed both ConfigHub AND the delivery controller.\n\n## Delivery path disambiguation\n\ncub-scout doesn't classify the *delivery* path in ownership detection — it just records the unit slug. To find out *how* a ConfigHub Unit got to the cluster, walk the labels:\n\n| If you also see... | The delivery path is... |\n|-------------------|------------------------|\n| `argocd.argoproj.io\u002Finstance` | ConfigHub-via-Argo (typically OCI) |\n| `kustomize.toolkit.fluxcd.io\u002Fname` | ConfigHub-via-Flux Kustomization |\n| `helm.toolkit.fluxcd.io\u002Fname` | ConfigHub-via-Flux HelmRelease |\n| Neither | Either a direct `cub` apply or an unusual delivery path; check `cub unit get \u003Cslug>` for the target |\n\nThe `compare source-truth --strategy \u003Cname>` verbs cover the four ConfigHub-aware strategies explicitly:\n- `confighub-oci-argo` — ConfigHub authors a Unit, renders to OCI, Argo CD reads OCI, applies to cluster\n- `confighub-oci-flux` — Same authoring chain, Flux is the deliverer\n- (helm \u002F git strategies aren't ConfigHub-authoritative; they describe vanilla Argo \u002F Flux)\n\n## Connected-mode evidence enrichment\n\nWhen cub-scout is run **connected** (`cub auth login`), additional ConfigHub-side evidence is layered onto the resource:\n\n- `confighubUrl` — the ConfigHub GUI deep-link to the unit's revision\n- `incomingBindings[]` — the upstream units feeding this unit via ConfigHub Links (#438)\n- per-field `bindingSource` — which Link supplies a specific field's value (#439)\n- `compare three-way` shows the full DRY (ConfigHub) \u002F WET (rendered) \u002F LIVE (cluster) trio\n- `compare source-truth --strategy confighub-oci-{argo,flux}` runs the strategy-typed verdict over all three surfaces\n\nStandalone-mode cub-scout still classifies as `OwnerConfigHub` (the label is on the live resource), but the connected-mode evidence isn't available. Receipts record this as `OmissionConfigHubUnitSubject`.\n\n## Worked example\n\n```bash\n$ kubectl get deploy api -n prod -o yaml | yq '.metadata.labels, .metadata.annotations, .metadata.managedFields[].manager'\nlabels:\n  confighub.com\u002FUnitSlug: payments-api\n  argocd.argoproj.io\u002Finstance: payments-app\n  app: api\nannotations:\n  confighub.com\u002FSpaceName: payments\n  argocd.argoproj.io\u002Ftracking-id: \"payments-app:apps\u002FDeployment:prod\u002Fapi\"\nmanagers:\n  - argocd-controller\n  - kubectl-edit                                          # uh oh\n```\n\ncub-scout reads this as:\n\n```\n$ cub-scout explain deploy\u002Fapi -n prod\nResource: Deployment\u002Fapi in prod\n  Owner:    ConfigHub unit \"payments-api\" in space \"payments\" (label:confighub.com\u002FUnitSlug)\n  Delivered via: Argo CD application \"payments-app\" (label:argocd.argoproj.io\u002Finstance)\n  Drift:    Detected\n  Mutation cause: manual-edit (manager: kubectl-edit; controller co-signal: argocd-controller)\n  ConfigHub URL: https:\u002F\u002Fhub.confighub.com\u002Fp\u002Fpayments\u002Fu\u002Fpayments-api    (connected mode)\n```\n\nThe classifier correctly identifies BOTH the source of truth (ConfigHub Unit) and the delivery path (Argo). The mutation cause is `manual-edit` despite the controller co-signal — that's the attribution layer's job.\n\n## Edge cases\n\n- **`confighub.com\u002FUnitSlug` annotation without the label**: Some resources only get the annotation. cub-scout's second branch in `detectConfigHubOwnership` catches this. `SpaceName` is still read from annotations (not labels) for consistency.\n- **ConfigHub-managed without a delivery controller**: A `cub apply` directly to the cluster (no Argo \u002F Flux in the middle) leaves only `confighub.com\u002FUnitSlug` on the resource. Ownership classifies as `OwnerConfigHub`; the controller writer is... whatever wrote it (often a `kubectl-*` form), which means `cause=manual-edit` even though the user intended a controlled apply. This is a known artifact of the `cub apply` path; #410\u002F#428 triad work is the long-term fix.\n- **ConfigHub via Helm (not Flux helm-controller)**: When ConfigHub renders to a Helm chart that's then handed to Argo's Helm renderer, the resource has `confighub.com\u002FUnitSlug` + `argocd.argoproj.io\u002Finstance` + `app.kubernetes.io\u002Fmanaged-by: Helm`. Detection priority: ConfigHub wins; controller co-signal recognizes `argocd-controller`. The Helm labels are an artifact of the chart, not evidence of a Helm-specific delivery.\n- **`OwnerConfigHub` with `cause=unknown`**: Older clusters that stripped `managedFields` produce this — the unit slug is there but cub-scout can't tell *who* wrote the live state. The attribution layer emits `cause=unknown` with an `OmissionManagedFields` entry rather than guessing.\n\n## References\n\n- Code: `pkg\u002Fagent\u002Fownership.go` `detectConfigHubOwnership`, `pkg\u002Fagent\u002Fmanager_strings.go` `controllerManagersForOwner(OwnerConfigHub, ...)`\n- Upstream: ConfigHub label spec — `confighub.com\u002FUnitSlug`, `confighub.com\u002FSpaceName`, `confighub.com\u002FSpaceID`, `confighub.com\u002FRevisionNum`\n- Related skills:\n  - [`scout-observe`](..\u002Fscout-observe\u002FSKILL.md) — the umbrella ownership detector\n  - [`scout-attribute`](..\u002Fscout-attribute\u002FSKILL.md) — per-field attribution; recognizes ConfigHub-via-Argo and ConfigHub-via-Flux controller co-signals\n  - [`scout-compare`](..\u002Fscout-compare\u002FSKILL.md) — `compare three-way` and `compare source-truth` use ConfigHub as the DRY layer\n  - [`scout-govern`](..\u002Fscout-govern\u002FSKILL.md) — `history`, `impact`, `views resolve` are ConfigHub-aware\n  - [`scout-verify`](..\u002Fscout-verify\u002FSKILL.md) — receipts add a `confighub-unit:\u002F\u002F` subject in connected mode\n  - [`observe-argocd`](..\u002Fobserve-argocd\u002FSKILL.md), [`observe-flux`](..\u002Fobserve-flux\u002FSKILL.md) — the delivery paths\n- Examples: [`examples\u002Fargo-import-confighub-demo\u002F`](..\u002F..\u002Fexamples\u002Fargo-import-confighub-demo\u002F), [`examples\u002Fflux-import-confighub-demo\u002F`](..\u002F..\u002Fexamples\u002Fflux-import-confighub-demo\u002F), [`examples\u002Fconnect-and-compare\u002F`](..\u002F..\u002Fexamples\u002Fconnect-and-compare\u002F)\n\n## Constraints\n\n- This skill is read-only. ConfigHub Unit mutation, space creation, target binding, etc. are all `cub` operations and out of allowed-tools.\n- ConfigHub detection priority is INTENTIONAL — a ConfigHub-managed resource classifies as `OwnerConfigHub` even when Argo \u002F Flux labels are also present. Don't reverse the order.\n- Connected-mode evidence enrichment requires `cub auth login`. Standalone-mode users get correct ownership classification but no `confighubUrl`, no `incomingBindings`, no DRY\u002FWET\u002FLIVE compare. Surface this as an omission, not silent missing data.\n",{"name":5,"phase":56,"description":7,"allowed-tools":57},"cross-cutting","Bash(.\u002Fcub-scout doctor *) Bash(cub-scout doctor *) Bash(cub scout doctor *) Bash(.\u002Fcub-scout explain *) Bash(cub-scout explain *) Bash(cub scout explain *) Bash(.\u002Fcub-scout trace *) Bash(cub-scout trace *) Bash(cub scout trace *) Bash(.\u002Fcub-scout map list *) Bash(.\u002Fcub-scout map workloads *) Bash(.\u002Fcub-scout map orphans *) Bash(cub-scout map list *) Bash(cub-scout map workloads *) Bash(cub-scout map orphans *) Bash(cub scout map list *) Bash(cub scout map workloads *) Bash(cub scout map orphans *) Bash(.\u002Fcub-scout compare three-way *) Bash(cub-scout compare three-way *) Bash(cub scout compare three-way *) Bash(.\u002Fcub-scout compare drift *) Bash(cub-scout compare drift *) Bash(cub scout compare drift *) Bash(.\u002Fcub-scout compare source-truth *) Bash(cub-scout compare source-truth *) Bash(cub scout compare source-truth *) Bash(.\u002Fcub-scout history *) Bash(cub-scout history *) Bash(cub scout history *) Bash(.\u002Fcub-scout impact *) Bash(cub-scout impact *) Bash(cub scout impact *) Bash(kubectl get *) Bash(kubectl describe *) Bash(kubectl get --show-managed-fields *) Bash(cub space list *) Bash(cub unit get *) Bash(cub unit list *) Bash(cub link get *) Bash(cub link list *) Bash(cub view get *) Bash(cub view list *) Bash(cub unit-event list *) Bash(cub resource list *) Bash(cub release list *) Bash(cub changeset list *) Bash(cub auth status)","main","261862e7ec5e5c93ce377ccfd6b583f5ac03c95c","skills\u002Fobserve-confighub-managed",1,"https:\u002F\u002Fgithub.com\u002Fconfighub\u002Fcub-scout","https:\u002F\u002Fconfighub.com","https:\u002F\u002Fgithub.com\u002Fconfighub","http:\u002F\u002Fwww.confighub.com","Public repo for ConfigHub","2026-11-14 03:24:15",{"source":8,"skillName":5,"commands":69,"prompt":79,"zipAvailable":80},[70,73,76],{"tool":71,"command":72},"npx","npx skills add confighub\u002Fcub-scout --skill observe-confighub-managed",{"tool":74,"command":75},"bunx","bunx skills add confighub\u002Fcub-scout --skill observe-confighub-managed",{"tool":77,"command":78},"pnpm","pnpm dlx skills add confighub\u002Fcub-scout --skill observe-confighub-managed","安装技能，技能地址：https:\u002F\u002Fgithub.com\u002Fconfighub\u002Fcub-scout\u002Fblob\u002Fmain\u002Fskills\u002Fobserve-confighub-managed\u002FSKILL.md",true,[],[83,113,132,149,173,194],{"skillNo":84,"name":85,"nameZh":6,"description":86,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":87,"categories":88,"keywords":94,"publishedAt":51},"01M6CBPQHTK7YGVZD3MMH1328H","triage-unhealthy-workload","Use when the user is responding to a broken Kubernetes workload UNDER TIME PRESSURE — pager-going-off, CI-red, \"prod is down\" framing. Natural phrasing: \"deploy\u002Fapi is CrashLoopBackOff, what now?\", \"the rollout is stuck, help\", \"this pod won't start\", \"pager fired on payments\", \"everything is red in argocd\", \"what should I check first?\", \"give me a triage plan for this workload\". Composes doctor → explain → trace into a tight ~30-second loop the operator can run in a pager-acknowledged context. Do NOT load for: a planned investigation without urgency (use scout-diagnose directly), a drift question (use investigate-drift), or anything mutating (cub-scout never mutates — route to kubectl with the user driving).","https:\u002F\u002Fgithub.com\u002Fconfighub\u002Fcub-scout\u002Fblob\u002Fmain\u002Fskills\u002Ftriage-unhealthy-workload\u002FSKILL.md",[89],{"categoryNo":90,"categoryName":91,"taxonomyType":92,"taxonomyTypeDesc":93},"01JBSEEDCAT000000000000011","运维与部署","SCENARIO","使用场景",[95,96,97,98,99,47,100,101,102,103,44,104,43,105,106,107,36,108,109,23,110,27,29,111,30,112,28],"triage","workload","triage unhealthy workload","kubernetes","diagnose","logs","ci","payments","api","loop","check","broken","question","rollout","never","route","time","now",{"skillNo":114,"name":115,"nameZh":6,"description":116,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":117,"categories":118,"keywords":120,"publishedAt":51},"01M6CBPKYVREY83CQYNFW6BVD0","scout-verify","Use when the user wants a TYPED, FINGERPRINTED, IMMUTABLE evidence artifact about a Kubernetes resource — the Verify verb group of cub-scout (the receipt capability shipped in #446). Natural phrasing: \"produce a receipt that this is in compliance\", \"give me an attestation that the cluster matches Git\", \"I need a verifiable record for the audit trail\", \"build a receipt verifying no manual edits since deploy\", \"verify deploy\u002Fapi against source-truth and save the artifact\", \"validate this receipt has not been tampered with\", \"show me what receipts we have\", \"is this receipt tampered with?\", \"attach evidence to my CI gate\". Load whenever intent is receipt \u002F attestation \u002F evidence-artifact \u002F tamper-evident-record \u002F verified-record \u002F audit-trail \u002F postmortem-evidence \u002F acceptance-judge-input. Do NOT load for: a live comparison without a persisted artifact (use scout-compare), interpreting a single field's provenance (use scout-attribute), or actually applying a fix (cub-scout never mutates — route to cub \u002F argocd \u002F kubectl with the user driving).","https:\u002F\u002Fgithub.com\u002Fconfighub\u002Fcub-scout\u002Fblob\u002Fmain\u002Fskills\u002Fscout-verify\u002FSKILL.md",[119],{"categoryNo":90,"categoryName":91,"taxonomyType":92,"taxonomyTypeDesc":93},[121,122,123,98,124,125,101,126,127,103,45,44,128,41,40,37,129,36,109,130,23,25,110,22,30,131,33,20,28],"verify","scout verify","scout","acceptance","produce","attestation","provenance","postmortem","fix","evidence","app",{"skillNo":133,"name":134,"nameZh":6,"description":135,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":136,"categories":137,"keywords":138,"publishedAt":51},"01M6CBPF8WZBM7F9X096WT8PJD","scout-observe","Use when the user wants to SEE what is running in a Kubernetes cluster, who owns it, and how it is structured — the read-only Observe verb group of cub-scout. Natural phrasing: \"what is running in my cluster?\", \"give me a map of resources\", \"who owns this Deployment?\", \"trace this back to its source\", \"show me the ownership tree\", \"scan this cluster for risk\", \"dump the cluster as JSON\", \"stream cluster events\", \"run cub-scout as a bot\", \"what is the connection status?\", \"is this cluster healthy?\". Load when intent is observe \u002F inventory \u002F map \u002F show \u002F list \u002F trace \u002F scan \u002F dump \u002F stream \u002F bot \u002F health-check over a Kubernetes cluster. Do NOT load for: explaining WHY something is broken (use scout-diagnose), comparing cluster state to intended state (use scout-compare), provenance of individual field values (use scout-attribute), or any action that mutates the cluster (cub-scout never mutates — route to cub or kubectl with the user driving).","https:\u002F\u002Fgithub.com\u002Fconfighub\u002Fcub-scout\u002Fblob\u002Fmain\u002Fskills\u002Fscout-observe\u002FSKILL.md",[],[19,139,123,140,98,99,141,47,100,142,127,143,45,44,106,36,144,109,145,146,23,25,26,147,29,30,32,148,28],"scout observe","bot","deployment","risk","inventory","version","only","hooks","health-check","meaning",{"skillNo":150,"name":151,"nameZh":6,"description":152,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":153,"categories":154,"keywords":158,"publishedAt":51},"01M6CBPBM5J9PX4H8CE628AY5X","scout-mcp","Use when the user wants to expose cub-scout to an AI agent over MCP, wants a deterministic AI-ready snapshot of cluster context, or wants cub-scout running as a read-only event bot — the Integrate verb group. Natural phrasing: \"start the MCP server\", \"expose cub-scout to Claude \u002F Codex \u002F my agent\", \"give me an AI-ready context pack of this cluster\", \"set up the MCP gateway\", \"what MCP tools does cub-scout expose?\", \"run cub-scout as a bot\", \"produce JSON context for an LLM to reason about this cluster\". Load whenever intent is mcp \u002F mcp-gateway \u002F mcp-serve \u002F context-pack \u002F bot \u002F agent-context \u002F ai-snapshot \u002F llm-context \u002F model-context-protocol. Do NOT load for: actually running a non-integrate verb (those are scout-observe \u002F scout-diagnose \u002F scout-compare \u002F scout-attribute \u002F scout-ingest \u002F scout-govern \u002F scout-verify), or `cub` MCP integration (that's a separate tool surface).","https:\u002F\u002Fgithub.com\u002Fconfighub\u002Fcub-scout\u002Fblob\u002Fmain\u002Fskills\u002Fscout-mcp\u002FSKILL.md",[155],{"categoryNo":156,"categoryName":157,"taxonomyType":92,"taxonomyTypeDesc":93},"01JBSEEDCAT000000000000023","Skill与智能体开发",[159,160,123,140,161,162,50,163,164,48,165,166,44,167,41,168,169,145,170,171,19,30,33,172,28],"MCP","scout mcp","mcp server","ai agent","config","run","server","SET","model","read","snapshot","ready","up","agent-context",{"skillNo":174,"name":175,"nameZh":6,"description":176,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":177,"categories":178,"keywords":179,"publishedAt":51},"01M6CBP7D72G704FWGRXNB6F9T","scout-ingest","Use when the user wants to ADOPT existing Kubernetes \u002F GitOps workload structure into ConfigHub after observing the live cluster — the adoption\u002Fimport verb group of cub-scout. Natural phrasing: \"discover workloads in this cluster and propose ConfigHub units\", \"show me the import proposal before I apply\", \"import this Argo Application set\", \"bring my Flux Kustomizations into ConfigHub\", \"preview what would land in ConfigHub if I imported this repo\", \"parse my git repo as a ConfigHub import bundle\", \"import a cluster aggregator\", \"what would --git-path produce for this repo?\". Load whenever intent is adopt \u002F import \u002F ingest \u002F preview \u002F propose \u002F parse-repo \u002F discovery \u002F aggregator \u002F bring-into-confighub \u002F what-would-confighub-see. Do NOT load for: questions about who changed a resource, whether it was edited by hand or drifted (use scout-attribute or investigate-drift); reading an exported `kubectl get -o yaml` dump to answer a question about the cluster (that is not an import); basic live-cluster inventory (use scout-observe), troubleshooting (use scout-diagnose), comparing live state to ConfigHub (use scout-compare), or the actual write to ConfigHub via `cub variant upload` (that is `cub`, not cub-scout — route to cub skills). Important: `cub-scout import apply` IS the mutating write into ConfigHub — this skill teaches the read-only preview path and explicitly refuses to invoke `import apply` itself.","https:\u002F\u002Fgithub.com\u002Fconfighub\u002Fcub-scout\u002Fblob\u002Fmain\u002Fskills\u002Fscout-ingest\u002FSKILL.md",[],[180,181,123,98,99,48,46,125,182,166,143,183,45,44,41,184,107,168,185,37,36,145,19,23,25,186,187,188,189,131,33,190,191,192,193],"ingest","scout ingest","adoption","discovery","repo","write","structure","aggregator","adopt","argo","reading","exported","invoke","parse",{"skillNo":195,"name":196,"nameZh":6,"description":197,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":198,"categories":199,"keywords":200,"publishedAt":51},"01M6CBP32CYJT8DJSGNCRWXQTM","scout-govern","Use when the user wants to consume CONNECTED ConfigHub governance signals from cub-scout — the Govern verb group. Natural phrasing: \"show me the ChangeSet history for this unit\", \"what is the blast radius if I change this unit?\", \"which clusters in my fleet are outliers?\", \"show me yesterday's connected summary\", \"render this view across the fleet\", \"audit who changed this\", \"where did the last apply come from?\", \"list ConfigHub bundles I have\", \"show me the catalog of past snapshots\". Load whenever intent is history \u002F impact \u002F blast-radius \u002F fleet-outliers \u002F summary \u002F view \u002F audit \u002F bundle \u002F catalog \u002F connected-context. Do NOT load for: live cluster comparison (use scout-compare), receipts (use scout-verify), inventory of running pods (use scout-observe), or any mutation via cub. Most of this skill requires `cub auth login` — say so upfront.","https:\u002F\u002Fgithub.com\u002Fconfighub\u002Fcub-scout\u002Fblob\u002Fmain\u002Fskills\u002Fscout-govern\u002FSKILL.md",[],[201,123,202,50,203,204,205,143,121,45,44,42,41,37,206,36,207,208,209,19,23,25,210,30,211,31,33,212,213,34,214,28],"scout govern","change","governance","blast radius","audit","catalog","diff","say","snapshots","project","mutation","render","blast-radius","inspect"]