Skip to content

feat(operator): report observed application identity - #709

Merged
lilienblum merged 6 commits into
mainfrom
lilienblum/alien-972-operator-release-receipt
Sep 25, 2026
Merged

lilienblum merged 6 commits into
mainfrom
lilienblum/alien-972-operator-release-receipt

Conversation

@lilienblum

@lilienblum lilienblum commented Sep 24, 2026 •

Copy link
Copy Markdown
Contributor

Summary

The Remote Operator now reports which application release is running in each deployment. This release is the customer's application, not the Operator image.

  • Every permission tier reports the release. Before this change, only Operators with the observe permission sent the version-only currentRelease, so an Operator installed with diagnostics or remediation permission sent no application version. The new OperatorConfig::reports_application_release() check covers all three tiers. Raw inventory collection still requires observe, so this does not change what the Operator is permitted to do.
  • New optional application field on the /v1/sync payload. It carries the Helm chart and the container images, with digests, that the Operator reads from the observed Kubernetes workloads. The report is built only from the current sync's observe pass, never from inventory kept from earlier passes:
    • Chart: taken from the helm.sh/chart label. The version starts at the first hyphen followed by a MAJOR.MINOR.PATCH version, and _ is converted back to +. The chart is reported only when every labelled workload names the same chart.
    • Images: taken from the pod status.containerStatuses[]. Each entry is keyed by the workload's inventory rawIdentity and the container name. The digest comes from imageID only when it is a repo@sha256:<hex> reference. A bare sha256: value is a local image ID, so it is omitted.
    • complete is false when a workload kind could not be listed. In that case the chart and images cover only the workloads the Operator could read.
    • The field is omitted when the workloads have no chart label and no images.
  • Supporting data. Kubernetes pod statuses now carry containers (name, image, digest), and observed resource samples carry the distinct images of their pods. Both are optional and omitted when empty.
  • Manager forwarding. The Manager accepts application and forwards it to the deployment store through ReconcileInput::application(). The existing into_parts() signature is unchanged, so current store implementations still compile.

Compatibility

  • An older Manager ignores the new field, because its sync request type does not reject unknown fields.
  • A new Operator works against an older Manager. All new fields are optional, and currentRelease works as before.

Wire shape

"application": {
  "source": "kubernetes",
  "chartName": "shop",
  "chartVersion": "1.4.0",
  "images": [
    {
      "workload": "apps/v1:Deployment:shop:api",
      "container": "api",
      "image": "registry.example.com/shop/api:1.4.0",
      "digest": "sha256:<64 hex>"
    }
  ],
  "complete": true,
  "observedAt": "2026-09-24T10:00:00Z"
}

source, complete and observedAt are always present. The other fields are omitted when empty.

Not included

This PR adds no ECS image reporting. The ECS Operator's task role cannot read the application's services or task definitions, and the installation does not identify which services belong to the application. Adding that needs new IAM grants and a way to select those services. On ECS, the Operator now reports the OPERATOR_RELEASE_VERSION version in currentRelease.

Generated artifacts

  • pnpm run generate:manager-rust-sdk (Manager OpenAPI and the Rust SDK inputs)
  • pnpm generate in packages/core (zod schemas). The new types are exported from packages/core/src/index.ts.
  • Manager TypeScript SDK: regenerated with Speakeasy 1.680.11 following client-sdks/manager/scripts/generate-typescript-sdk.sh. That CLI rejects the script's --skip-versioning flag, so the generator ran without it and the version bump it made (3.3.24) was reverted. agentSync now sends application, and resource samples carry images. The client also picks up the Vault secret endpoints that were already in the spec but missing from the client.
  • The /v1/sync body is documented as AgentSyncRequest again (the name in the released clients) instead of the internal AgentSyncWireRequest, so regenerating does not rename the TypeScript request type.

Validation

  • cargo nextest run -p alien-core -p alien-k8s-clients -p alien-observer -p alien-operator -p alien-manager -p alien-deployment --features alien-manager/openapi: 1224 passed, 1 skipped. This run was on the first head.
  • After the review fixes, cargo nextest run -p alien-core -p alien-operator -p alien-manager --lib --features alien-manager/openapi: 934 passed.
  • New tests:
    • Chart label parsing.
    • Digest taken from imageID for multiple containers, with no digest for a local image ID.
    • Chart omitted when workloads name different charts; report omitted when there is no data.
    • The report is marked incomplete when a workload kind could not be listed.
    • A sync loop against a stub Manager:
      • An ECS-style diagnostics Operator sends currentRelease.version. This test fails with the old observe-only check.
      • A Kubernetes Remote Operator runs the real observe pass against a stub Kubernetes API. It sends the exact application JSON, with the digest parsed from the pod's imageID. Inventory saved from an earlier pass does not change the report.
    • An Operator SyncInput serialized and then deserialized by the Manager request type.
  • Manager TypeScript SDK: pnpm -C client-sdks/manager/typescript build and node --test client-sdks/manager/scripts/typescript-sdk.test.mjs (3 passed; the new test checks that agentSyncRequestToJSON keeps application).
  • Final head: cargo nextest run -p alien-manager --features openapi --lib routes::sync (37 passed), cargo nextest run -p alien-operator (79 passed), cargo check -p alien-manager-api.
  • cargo check --workspace --tests --features alien-manager/openapi,alien-bindings/platform-sdk and pnpm -C packages/core build pass.

lilienblum and others added 2 commits September 24, 2026 14:28
Kubernetes pod statuses now carry each container's image and registry
digest (from the container status imageID), and observed resource
samples list the distinct images their pods run. Both fields are
optional and omitted when empty, so existing readers are unaffected.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Remote Operator installations now report the application release they
find on every permission tier. Before, only the `observe` tier reported
it, so an Operator installed with `diagnostics` or `remediation`
permission sent no application version at all. Raw inventory collection
still requires `observe`.

The sync payload gains an optional `application` report with the Helm
chart from the workloads' `helm.sh/chart` label and each running
container image with its digest. The Manager forwards it to the
deployment store through `ReconcileInput::application()`. Older
Managers ignore the field, and the Operator works unchanged against
them.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Sep 24, 2026 •

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-09-24T05:36:57.372280Z d19375a PR opened
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@greptile-apps

greptile-apps Bot commented Sep 24, 2026 •

Copy link
Copy Markdown

RetriggerConfidence Score: 5/5

The PR appears safe to merge; no outstanding finding or new actionable issue was identified.

Summary

The PR adds observed Kubernetes application chart and image identity to Operator sync, forwards it through the Manager, and updates the generated client contracts. Changes since the previous review build reports from the current observe pass, mark partial observations incomplete, correct chart parsing, and regenerate the Manager TypeScript SDK. They also adjust EKS Terraform provider authentication.

Diagram

sequenceDiagram
    participant K as Kubernetes
    participant O as Operator
    participant M as Manager
    participant S as Deployment store
    O->>K: Observe current workloads
    K-->>O: Labels and container statuses
    O->>M: Sync with application report
    M->>S: Reconcile with application report
Loading

Reviews (2) · Last reviewed commit: "fix(manager): regenerate the TypeScript ..."

Comment thread crates/alien-operator/src/loops/sync.rs Outdated
Comment thread crates/alien-operator/src/loops/observed_release.rs
Comment thread crates/alien-operator/src/loops/observed_release.rs
Comment thread client-sdks/manager/openapi.json Outdated

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: d19375a49a

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread client-sdks/manager/openapi.json Outdated
lilienblum and others added 3 commits September 24, 2026 15:16
Build the application report from this sync's observe pass instead of
inventory kept from earlier passes, so it cannot repeat old images.
Add `complete` so readers know when a workload kind could not be listed
and the report covers only part of the application. Require a full
MAJOR.MINOR.PATCH version when splitting `helm.sh/chart`, so a dotted
number inside a chart name is not taken as the version.

The Kubernetes sync test now runs the real observe pass against a stub
Kubernetes API.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…port (ALIEN-972)

Document the `POST /v1/sync` body as `AgentSyncRequest` again, the name
the released clients use, instead of the internal `AgentSyncWireRequest`.
Regenerate the Manager OpenAPI specs and the TypeScript client so
`agentSync` can send `application` and resource samples carry container
images. The client also picks up the Vault secret endpoints already in
the spec.

Generated with `pnpm run generate:manager-rust-sdk` and Speakeasy
1.680.11 (`generate-typescript-sdk.sh` steps; the pinned CLI rejects
`--skip-versioning`, so the version bump it makes was reverted).
@lilienblum

Copy link
Copy Markdown
Contributor Author

@greptileai review

@lilienblum
lilienblum enabled auto-merge (squash) September 25, 2026 07:45
…operator-release-receipt

# Conflicts:
#	crates/alien-cli/src/commands/operations/mod.rs
@lilienblum
lilienblum merged commit 681ca4b into main Sep 25, 2026
13 checks passed
@lilienblum
lilienblum deleted the lilienblum/alien-972-operator-release-receipt branch September 25, 2026 07:55
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant