Skip to content

HYPERFLEET-1017 - refactor: rename aggregated Available to LastKnownReconciled#127

Open
rafabene wants to merge 2 commits intoopenshift-hyperfleet:mainfrom
rafabene:rbenevid/HYPERFLEET-1017/rename-available-to-last-known-reconciled
Open

HYPERFLEET-1017 - refactor: rename aggregated Available to LastKnownReconciled#127
rafabene wants to merge 2 commits intoopenshift-hyperfleet:mainfrom
rafabene:rbenevid/HYPERFLEET-1017/rename-available-to-last-known-reconciled

Conversation

@rafabene
Copy link
Copy Markdown
Contributor

@rafabene rafabene commented May 5, 2026

Summary

  • Rename the aggregated Available condition to LastKnownReconciled across the entire codebase (service layer, tests, docs)
  • Sync OpenAPI spec from upstream hyperfleet-api-spec v1.0.11 (includes new PUT endpoints for cluster/nodepool statuses, updated LKR description)
  • Remove backward-compatibility migration code for the old Available condition name (not needed since v1.0 hasn't shipped)
  • Fix doc examples: correct Reconciled condition reason values to match code constants (ReadyAllReconciled, AllAdaptersReconciled)

Changes

Service layer (pkg/services/aggregation.go)

  • ConditionTypeAvailable kept for adapter-level conditions (unchanged)
  • New ConditionTypeLastKnownReconciled used for the aggregated condition
  • Removed migration path in parsePrevConditions that mapped legacy AvailableLastKnownReconciled

Tests (pkg/services/aggregation_test.go)

  • Updated all fixtures and test names to use LastKnownReconciled
  • Removed 2 precedence tests for legacy AvailableLastKnownReconciled migration

OpenAPI spec (openapi/openapi.yaml)

  • Synced from upstream hyperfleet-api-spec v1.0.11
  • Regenerated pkg/api/openapi/ from updated spec

Docs (docs/api-resources.md)

  • Fixed Reconciled condition reason/message in examples to match code

Test plan

  • make test — all unit tests pass (including updated aggregation tests)
  • make test-integration — integration tests
  • make verify-all — vet + lint + tests

@openshift-ci openshift-ci Bot requested review from aredenba-rh and jsell-rh May 5, 2026 22:55
@openshift-ci
Copy link
Copy Markdown

openshift-ci Bot commented May 5, 2026

[APPROVALNOTIFIER] This PR is NOT APPROVED

This pull-request has been approved by:
Once this PR has been reviewed and has the lgtm label, please assign jsell-rh for approval. For more information see the Code Review Process.

The full list of commands accepted by this bot can be found here.

Details Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 5, 2026

📝 Walkthrough

Summary by CodeRabbit

  • New Features

    • Added PUT endpoints to update cluster and nodepool statuses.
  • Changes

    • API version bumped to 1.0.11.
    • Status conditions updated: Mandatory condition LastKnownReconciled replaces Available; Reconciled and Ready remain (Ready marked deprecated in docs).
  • Documentation

    • Examples, guides, and search/query docs updated to show LastKnownReconciled and revised aggregation semantics.

Walkthrough

This PR replaces the aggregated status condition "Available" with "LastKnownReconciled" across API schema, docs, tests, and implementation. It adds api.ConditionTypeLastKnownReconciled, updates aggregation logic to compute LastKnownReconciled (including observed_generation, last_updated_time, last_transition_time and sticky/mixed-generation rules), changes aggregation return values and callers to include LastKnownReconciled, updates cluster/nodepool status builders, updates tests and docs, and bumps the OpenAPI version while adding PUT endpoints for updating cluster and nodepool statuses.

Sequence Diagram(s)

sequenceDiagram
    participant Client
    participant AggregationService as Aggregation Service
    participant AdapterStatuses as Adapter Status Sources
    participant PreviousState as Previous Conditions Store
    participant StatusComputation as Status Computation

    Client->>AggregationService: Trigger status aggregation / recompute
    AggregationService->>AdapterStatuses: Fetch per-adapter snapshots
    AdapterStatuses-->>AggregationService: Adapter conditions
    AggregationService->>PreviousState: Read previous conditions (incl. LastKnownReconciled / legacy Available)
    PreviousState-->>AggregationService: Prev-state map
    AggregationService->>StatusComputation: computeReconciled(adapterSnapshots)
    StatusComputation-->>AggregationService: Reconciled condition
    AggregationService->>StatusComputation: computeLastKnownReconciled(adapterSnapshots, prevState)
    StatusComputation-->>AggregationService: LastKnownReconciled condition
    AggregationService->>Client: Return aggregated conditions (Reconciled, LastKnownReconciled, Ready, per-adapter)
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 44.44% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly summarizes the primary change: renaming the aggregated Available condition to LastKnownReconciled across the codebase.
Description check ✅ Passed The description is well-related to the changeset, providing clear context about the rename, code changes, test updates, OpenAPI sync, and documentation fixes.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
openapi/openapi.yaml (1)

1195-1204: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Update the schema cardinality to match the new mandatory condition set.

These descriptions now say Ready, Reconciled, and LastKnownReconciled are all mandatory, but both schemas still allow minItems: 2. That leaves the public contract inconsistent and lets generated validators accept payloads that this PR says are invalid.

Suggested fix
     ClusterStatus:
       type: object
       required:
         - conditions
       properties:
         conditions:
           type: array
           items:
             $ref: '#/components/schemas/ResourceCondition'
-          minItems: 2
+          minItems: 3
     NodePoolStatus:
       type: object
       required:
         - conditions
       properties:
         conditions:
           type: array
           items:
             $ref: '#/components/schemas/ResourceCondition'
-          minItems: 2
+          minItems: 3

Also applies to: 1557-1570

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@openapi/openapi.yaml` around lines 1195 - 1204, The schema's conditions array
currently uses "minItems: 2" but the description lists three mandatory condition
types ("Ready", "Reconciled", "LastKnownReconciled"); update the schema(s) that
define the cluster/status conditions array (the entries containing "minItems: 2"
and the description block listing those three types) to use "minItems: 3" so the
OpenAPI contract enforces all three required conditions; apply the same change
to the second matching schema mentioned in the comment (the other block that
currently has minItems: 2 at the later location).
pkg/services/aggregation.go (1)

477-514: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Different false states are all reported as AdaptersNotAtSameGeneration.

computeLastKnownReconciledStatus returns False for missing reports and explicit adapter failures as well, but this function always emits the same false reason/message. That makes the new canonical condition misleading for dashboards and operators during the rollout, because “adapter failed” and “adapter hasn’t reported yet” are indistinguishable from a mixed-generation case.

Please branch the false reason/message by root cause before building the condition.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@pkg/services/aggregation.go` around lines 477 - 514,
computeLastKnownReconciled currently emits the same false reason/message; change
it to pick the false reason/message based on the root cause by inspecting
sameGenerationAllTrue(required, byAdapter), the individual adapter states in
byAdapter and whether any required adapter reports Available=False or is missing
a report: if status==api.ConditionTrue keep the existing "All required..."
reason/message; if any required adapter explicitly reports Available=False set
reason like "AdapterReportedNotAvailable" with a message naming that root cause;
else if required adapters are missing reports set reason like
"AdaptersMissingReports" with an explanatory message; otherwise (mixed
generations) keep "AdaptersNotAtSameGeneration". Use the existing helper calls
sameGenerationAllTrue, computeLastKnownReconciledStatus and the byAdapter map to
determine which branch to use and assign reason/message before returning the
api.ResourceCondition.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Outside diff comments:
In `@openapi/openapi.yaml`:
- Around line 1195-1204: The schema's conditions array currently uses "minItems:
2" but the description lists three mandatory condition types ("Ready",
"Reconciled", "LastKnownReconciled"); update the schema(s) that define the
cluster/status conditions array (the entries containing "minItems: 2" and the
description block listing those three types) to use "minItems: 3" so the OpenAPI
contract enforces all three required conditions; apply the same change to the
second matching schema mentioned in the comment (the other block that currently
has minItems: 2 at the later location).

In `@pkg/services/aggregation.go`:
- Around line 477-514: computeLastKnownReconciled currently emits the same false
reason/message; change it to pick the false reason/message based on the root
cause by inspecting sameGenerationAllTrue(required, byAdapter), the individual
adapter states in byAdapter and whether any required adapter reports
Available=False or is missing a report: if status==api.ConditionTrue keep the
existing "All required..." reason/message; if any required adapter explicitly
reports Available=False set reason like "AdapterReportedNotAvailable" with a
message naming that root cause; else if required adapters are missing reports
set reason like "AdaptersMissingReports" with an explanatory message; otherwise
(mixed generations) keep "AdaptersNotAtSameGeneration". Use the existing helper
calls sameGenerationAllTrue, computeLastKnownReconciledStatus and the byAdapter
map to determine which branch to use and assign reason/message before returning
the api.ResourceCondition.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Enterprise

Run ID: 4f7f6aee-c198-432b-a2e6-76055dfae55c

📥 Commits

Reviewing files that changed from the base of the PR and between 60956b9 and d6f5bbd.

📒 Files selected for processing (6)
  • openapi/openapi.yaml
  • pkg/api/status_types.go
  • pkg/services/aggregation.go
  • pkg/services/aggregation_test.go
  • pkg/services/cluster_test.go
  • pkg/services/node_pool_test.go

@rafabene rafabene force-pushed the rbenevid/HYPERFLEET-1017/rename-available-to-last-known-reconciled branch from 7c6c332 to da7f311 Compare May 5, 2026 23:13
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
docs/api-operator-guide.md (1)

147-167: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Include Reconciled in this response example.

The implementation still persists three top-level synthetic conditions — Ready, Reconciled, and LastKnownReconciled — so this example now under-documents the actual response shape. That’s easy for operators to copy into broken jq filters or dashboards.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@docs/api-operator-guide.md` around lines 147 - 167, Update the example
response under "status" to reflect the actual persisted synthetic conditions by
adding a third condition object for "Reconciled" (matching the existing "type",
"status", "observed_generation", and "last_transition_time" fields used for
"Ready" and "LastKnownReconciled"); ensure the conditions array contains objects
with "type": "Reconciled", a "status" value (e.g., "True"/"False"),
"observed_generation": 1 and a realistic "last_transition_time" timestamp so the
example matches the real API shape that includes Ready, Reconciled, and
LastKnownReconciled.
🧹 Nitpick comments (2)
pkg/services/aggregation.go (1)

110-138: ⚡ Quick win

Rename the aggregated available value to lastKnownReconciled.

This function is now the semantic boundary between adapter Available and aggregated LastKnownReconciled. Keeping the old identifier here makes those two concepts easy to confuse again in callers and follow-up changes.

Suggested rename
 func AggregateResourceStatus(ctx context.Context, in AggregateResourceStatusInput) (
-	reconciled, available api.ResourceCondition, adapterConditions []api.ResourceCondition,
+	reconciled, lastKnownReconciled api.ResourceCondition, adapterConditions []api.ResourceCondition,
 ) {
 	prevReconciled, prevAvail, prevAdapterByType := parsePrevConditions(ctx, in.PrevConditionsJSON)

 	reports := normalizeAdapterReportsForAggregation(ctx, in.AdapterStatuses, in.RequiredAdapters, in.ResourceGeneration)

 	reconciled = computeReconciled(
 		in.ResourceGeneration,
 		in.RefTime,
 		in.DeletedTime,
 		prevReconciled,
 		in.RequiredAdapters,
 		reports,
 		in.HasChildResources,
 	)
-	available = computeLastKnownReconciled(
+	lastKnownReconciled = computeLastKnownReconciled(
 		in.RefTime,
 		prevAvail,
 		in.RequiredAdapters,
 		reports,
 	)
 	adapterConditions = computeAdapterConditions(in.RequiredAdapters, reports, prevAdapterByType, in.RefTime)
-	return reconciled, available, adapterConditions
+	return reconciled, lastKnownReconciled, adapterConditions
 }
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@pkg/services/aggregation.go` around lines 110 - 138, The aggregated variable
named available in AggregateResourceStatus should be renamed to
lastKnownReconciled to reflect that this function produces the aggregated
LastKnownReconciled (distinct from adapter Available); update the local variable
declaration and assignment (currently assigned from computeLastKnownReconciled)
and the function's returned identifier list so the third return remains
adapterConditions and the second return is lastKnownReconciled, and update any
internal references and the function comment to use lastKnownReconciled instead
of available (references: AggregateResourceStatus, computeLastKnownReconciled,
adapterConditions).
pkg/api/status_types.go (1)

31-37: Add an explicit consumer migration note.

Resource-level status.conditions.Available is being replaced here, while adapter-level conditions[type=Available] stays unchanged. A release note or upgrade note calling out that distinction would reduce Sentinel/dashboard regressions during rollout.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@pkg/api/status_types.go` around lines 31 - 37, Add an explicit
upgrade/migration note that resource-level status.conditions.Available
(referenced by ConditionTypeAvailable in pkg/api/status_types.go) is being
replaced while adapter-level conditions[type=Available] remain unchanged; update
the release notes/upgrade docs to call out this distinction, mention any
expected dashboards/Sentinel impacts and recommended actions (e.g., remap
watchers or dashboards to the new resource-level condition name or keep using
adapter-level condition where appropriate), and include an example mapping to
avoid regressions during rollout.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@openapi/openapi.yaml`:
- Line 53: Docs state three mandatory status conditions ("LastKnownReconciled",
"Ready", "Reconciled") but the schemas for ClusterStatus.conditions and
NodePoolStatus.conditions still use minItems: 2; update both schema definitions
to minItems: 3 and update their descriptions/examples to explicitly list the
three mandatory condition names so generated clients/validators enforce the
3-item minimum (locate the ClusterStatus.conditions and
NodePoolStatus.conditions entries in openapi.yaml and change minItems: 2 ->
minItems: 3 and adjust the human-readable description accordingly).

---

Outside diff comments:
In `@docs/api-operator-guide.md`:
- Around line 147-167: Update the example response under "status" to reflect the
actual persisted synthetic conditions by adding a third condition object for
"Reconciled" (matching the existing "type", "status", "observed_generation", and
"last_transition_time" fields used for "Ready" and "LastKnownReconciled");
ensure the conditions array contains objects with "type": "Reconciled", a
"status" value (e.g., "True"/"False"), "observed_generation": 1 and a realistic
"last_transition_time" timestamp so the example matches the real API shape that
includes Ready, Reconciled, and LastKnownReconciled.

---

Nitpick comments:
In `@pkg/api/status_types.go`:
- Around line 31-37: Add an explicit upgrade/migration note that resource-level
status.conditions.Available (referenced by ConditionTypeAvailable in
pkg/api/status_types.go) is being replaced while adapter-level
conditions[type=Available] remain unchanged; update the release notes/upgrade
docs to call out this distinction, mention any expected dashboards/Sentinel
impacts and recommended actions (e.g., remap watchers or dashboards to the new
resource-level condition name or keep using adapter-level condition where
appropriate), and include an example mapping to avoid regressions during
rollout.

In `@pkg/services/aggregation.go`:
- Around line 110-138: The aggregated variable named available in
AggregateResourceStatus should be renamed to lastKnownReconciled to reflect that
this function produces the aggregated LastKnownReconciled (distinct from adapter
Available); update the local variable declaration and assignment (currently
assigned from computeLastKnownReconciled) and the function's returned identifier
list so the third return remains adapterConditions and the second return is
lastKnownReconciled, and update any internal references and the function comment
to use lastKnownReconciled instead of available (references:
AggregateResourceStatus, computeLastKnownReconciled, adapterConditions).
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Enterprise

Run ID: 2baa6cf6-a79c-4b58-b84c-61a89fb7ef82

📥 Commits

Reviewing files that changed from the base of the PR and between 7c6c332 and da7f311.

📒 Files selected for processing (9)
  • docs/api-operator-guide.md
  • docs/api-resources.md
  • docs/search.md
  • openapi/openapi.yaml
  • pkg/api/status_types.go
  • pkg/services/aggregation.go
  • pkg/services/aggregation_test.go
  • pkg/services/cluster_test.go
  • pkg/services/node_pool_test.go
🚧 Files skipped from review as they are similar to previous changes (1)
  • docs/api-resources.md

Comment thread openapi/openapi.yaml
@rafabene rafabene force-pushed the rbenevid/HYPERFLEET-1017/rename-available-to-last-known-reconciled branch from da7f311 to 964de33 Compare May 5, 2026 23:31
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🧹 Nitpick comments (1)
pkg/services/cluster.go (1)

225-240: ⚡ Quick win

Update stale method comment that still references Available.

The implementation now aggregates lastKnownReconciled (Line 225 / Line 240), but the method comment above still says “Reconciled, Available.” Please align that comment to prevent future confusion between adapter-level Available and aggregated LastKnownReconciled.

As per coding guidelines, "Focus on major issues impacting performance, readability, maintainability and security. Avoid nitpicks and avoid verbosity."

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@pkg/services/cluster.go` around lines 225 - 240, The comment above
AggregateResourceStatus is stale: it still references "Reconciled, Available"
while the implementation now aggregates lastKnownReconciled and uses ready :=
reconciled / lastKnownReconciled; update the method comment to reflect the
current outputs (e.g., "Reconciled, LastKnownReconciled" or similar), and
clarify that adapter-level Available remains distinct from the aggregated
lastKnownReconciled produced by AggregateResourceStatus and returned in the
adapterConditions/lastKnownReconciled values.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@docs/api-operator-guide.md`:
- Line 332: Update the docs line for LastKnownReconciled to match runtime logic:
clarify that LastKnownReconciled=True requires adapters to report Available=True
for a common reconciled generation or that the controller's "sticky-true"
conditions have already been met; mixed-generation Available=True reports alone
do not necessarily set LastKnownReconciled=True unless the sticky-true path in
the aggregation logic (see the aggregation/availability handling in
pkg/services/aggregation.go, e.g., the sticky-true / aggregate status
evaluation) is satisfied.

In `@docs/api-resources.md`:
- Around line 56-57: Update all status examples and the status-fields note to
include the required synthesized condition "Reconciled" alongside "Ready" and
"LastKnownReconciled"; search for the examples that show only
"LastKnownReconciled" and "Ready" (occurrences near the examples around the
swapped snippets corresponding to the symbols Ready, Reconciled,
LastKnownReconciled) and add the "Reconciled" condition with appropriate "type"
and "status" entries so every example reflects the API contract's three
mandatory conditions.

---

Nitpick comments:
In `@pkg/services/cluster.go`:
- Around line 225-240: The comment above AggregateResourceStatus is stale: it
still references "Reconciled, Available" while the implementation now aggregates
lastKnownReconciled and uses ready := reconciled / lastKnownReconciled; update
the method comment to reflect the current outputs (e.g., "Reconciled,
LastKnownReconciled" or similar), and clarify that adapter-level Available
remains distinct from the aggregated lastKnownReconciled produced by
AggregateResourceStatus and returned in the
adapterConditions/lastKnownReconciled values.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Enterprise

Run ID: 25db7dd3-db39-4c52-8f37-d736014035e4

📥 Commits

Reviewing files that changed from the base of the PR and between da7f311 and 964de33.

📒 Files selected for processing (11)
  • docs/api-operator-guide.md
  • docs/api-resources.md
  • docs/search.md
  • openapi/openapi.yaml
  • pkg/api/status_types.go
  • pkg/services/aggregation.go
  • pkg/services/aggregation_test.go
  • pkg/services/cluster.go
  • pkg/services/cluster_test.go
  • pkg/services/node_pool_test.go
  • pkg/services/status_helpers.go

Comment thread docs/api-operator-guide.md Outdated
Comment thread docs/api-resources.md
@rafabene rafabene force-pushed the rbenevid/HYPERFLEET-1017/rename-available-to-last-known-reconciled branch from 964de33 to 8445ee0 Compare May 5, 2026 23:53
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

🧹 Nitpick comments (1)
pkg/services/cluster.go (1)

191-192: 💤 Low value

Stale comment references old condition name.

The comment says "Reconciled, Available, and per-adapter conditions" but should reference LastKnownReconciled to match the implementation.

📝 Suggested comment update
-// UpdateClusterStatusFromAdapters recomputes aggregated Reconciled, Available, and per-adapter conditions
+// UpdateClusterStatusFromAdapters recomputes aggregated Reconciled, LastKnownReconciled, and per-adapter conditions
 // from stored adapter rows and persists them to the cluster's status.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@pkg/services/cluster.go` around lines 191 - 192, Update the stale comment
above the UpdateClusterStatusFromAdapters function: replace the mention of
"Reconciled" with the current condition name "LastKnownReconciled" so the
comment reads that it recomputes aggregated LastKnownReconciled, Available, and
per-adapter conditions from stored adapter rows and persists them to the
cluster's status; ensure the comment text matches the implemented condition name
exactly.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@pkg/services/cluster.go`:
- Around line 191-192: Update the stale comment above the
UpdateClusterStatusFromAdapters function: replace the mention of "Reconciled"
with the current condition name "LastKnownReconciled" so the comment reads that
it recomputes aggregated LastKnownReconciled, Available, and per-adapter
conditions from stored adapter rows and persists them to the cluster's status;
ensure the comment text matches the implemented condition name exactly.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Enterprise

Run ID: 989a98bf-34b5-4c8d-8b81-aee2e44b2f33

📥 Commits

Reviewing files that changed from the base of the PR and between 964de33 and 8445ee0.

📒 Files selected for processing (11)
  • docs/api-operator-guide.md
  • docs/api-resources.md
  • docs/search.md
  • openapi/openapi.yaml
  • pkg/api/status_types.go
  • pkg/services/aggregation.go
  • pkg/services/aggregation_test.go
  • pkg/services/cluster.go
  • pkg/services/cluster_test.go
  • pkg/services/node_pool_test.go
  • pkg/services/status_helpers.go
🚧 Files skipped from review as they are similar to previous changes (1)
  • pkg/services/cluster_test.go

@rafabene rafabene force-pushed the rbenevid/HYPERFLEET-1017/rename-available-to-last-known-reconciled branch 2 times, most recently from d29226e to 72a1271 Compare May 6, 2026 00:14
Comment thread pkg/services/aggregation.go Outdated
Comment thread pkg/services/aggregation_test.go Outdated
@rafabene rafabene force-pushed the rbenevid/HYPERFLEET-1017/rename-available-to-last-known-reconciled branch from 72a1271 to f9e175b Compare May 8, 2026 17:19
Comment thread pkg/api/openapi/openapi.gen.go Outdated
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

This is a generated file that should not go to the repo

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Agreed — removed openapi.gen.go from tracking. It's already in .gitignore under /pkg/api/openapi/, so it was added accidentally.

Comment thread pkg/services/aggregation.go Outdated
Comment on lines +33 to +34
reasonReadyMissingAdapters = "ReadyMissingAdapters"
reasonReadyWaitingForChildren = "ReadyWaitingForChildren"
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Should these be Reconciled instead of Ready?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Good catch — renamed the constants and their string values from Ready* to Reconciled* prefix since they're used in computeReconciled(), not the deprecated Ready condition. Updated aggregation.go, tests, and doc examples.

…LastKnownReconciled

- Rename the aggregated Available condition to LastKnownReconciled
  across service layer, tests, docs, and OpenAPI spec
- Sync OpenAPI spec from upstream hyperfleet-api-spec v1.0.11
  (includes new PUT endpoints for cluster/nodepool statuses)
- Rename Reconciled condition reason constants from Ready* prefix
  to Reconciled* prefix to match their actual usage
- Fix doc examples: correct Reconciled condition reason values
  to match code constants (ReconciledAll, AllAdaptersReconciled)
@rafabene rafabene force-pushed the rbenevid/HYPERFLEET-1017/rename-available-to-last-known-reconciled branch from 225c50e to f08a379 Compare May 8, 2026 19:17
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
pkg/services/aggregation_test.go (1)

1207-1230: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Test may not be testing the intended behavior after migration removal.

This test uses api.ConditionTypeAvailable in prevConds, but per the past review discussion, the backward-compatibility migration that mapped AvailableLastKnownReconciled in parsePrevConditions was removed. The test still passes (since adapter "b" reports False, resulting in avail.Status == False), but it's not actually exercising the "sticky-break" logic it claims — the prev condition won't be recognized as prevAvail.

Consider updating this test to use api.ConditionTypeLastKnownReconciled in prevConds to properly test the sticky-break behavior.

🔧 Suggested fix
 	t.Run("Available False at tracked gen breaks prev=True sticky", func(t *testing.T) {
 		t.Parallel()
 		required := []string{"a", "b"}
 		prevConds := encodePrev(
 			api.ResourceCondition{
-				Type: api.ConditionTypeAvailable, Status: api.ConditionTrue, ObservedGeneration: 1,
+				Type: api.ConditionTypeLastKnownReconciled, Status: api.ConditionTrue, ObservedGeneration: 1,
 				CreatedTime: aggT0, LastUpdatedTime: aggT0, LastTransitionTime: aggT0,
 			},
 		)
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@pkg/services/aggregation_test.go` around lines 1207 - 1230, The test
"Available False at tracked gen breaks prev=True sticky" is constructing
prevConds with api.ConditionTypeAvailable but the compatibility migration was
removed, so the prev condition isn't treated as prevAvail; update the test to
use api.ConditionTypeLastKnownReconciled when calling encodePrev so the prior
sticky reconciliation state is recognized by AggregateResourceStatus (keep the
rest of the setup the same), referencing the test helper encodePrev, the
condition constant api.ConditionTypeLastKnownReconciled, and the function under
test AggregateResourceStatus to ensure the test actually exercises the
sticky-break logic.
openapi/openapi.yaml (1)

1262-1276: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Set minItems: 3 for ClusterStatus and NodePoolStatus conditions arrays.

Both ClusterStatus (line 1266) and NodePoolStatus (line 1632) document three mandatory conditions (Ready, Reconciled, LastKnownReconciled) but validate with minItems: 2. Update both to minItems: 3 to enforce the documented contract.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@openapi/openapi.yaml` around lines 1262 - 1276, The ClusterStatus and
NodePoolStatus schema definitions declare three mandatory conditions but
currently set conditions.minItems to 2; update the schemas named ClusterStatus
and NodePoolStatus by changing the conditions array property minItems from 2 to
3 so the OpenAPI contract enforces the documented three mandatory
ResourceCondition entries (the property to update is conditions under each of
the ClusterStatus and NodePoolStatus components).
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Outside diff comments:
In `@openapi/openapi.yaml`:
- Around line 1262-1276: The ClusterStatus and NodePoolStatus schema definitions
declare three mandatory conditions but currently set conditions.minItems to 2;
update the schemas named ClusterStatus and NodePoolStatus by changing the
conditions array property minItems from 2 to 3 so the OpenAPI contract enforces
the documented three mandatory ResourceCondition entries (the property to update
is conditions under each of the ClusterStatus and NodePoolStatus components).

In `@pkg/services/aggregation_test.go`:
- Around line 1207-1230: The test "Available False at tracked gen breaks
prev=True sticky" is constructing prevConds with api.ConditionTypeAvailable but
the compatibility migration was removed, so the prev condition isn't treated as
prevAvail; update the test to use api.ConditionTypeLastKnownReconciled when
calling encodePrev so the prior sticky reconciliation state is recognized by
AggregateResourceStatus (keep the rest of the setup the same), referencing the
test helper encodePrev, the condition constant
api.ConditionTypeLastKnownReconciled, and the function under test
AggregateResourceStatus to ensure the test actually exercises the sticky-break
logic.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Central YAML (base), Organization UI (inherited)

Review profile: ASSERTIVE

Plan: Enterprise

Run ID: 56668f77-5dad-493a-aae9-716c73edd894

📥 Commits

Reviewing files that changed from the base of the PR and between 964de33 and f08a379.

📒 Files selected for processing (11)
  • docs/api-operator-guide.md
  • docs/api-resources.md
  • docs/search.md
  • openapi/openapi.yaml
  • pkg/api/status_types.go
  • pkg/services/aggregation.go
  • pkg/services/aggregation_test.go
  • pkg/services/cluster.go
  • pkg/services/cluster_test.go
  • pkg/services/node_pool_test.go
  • pkg/services/status_helpers.go

…-break test

The test was using ConditionTypeAvailable in prevConds, but
parsePrevConditions looks for ConditionTypeLastKnownReconciled.
Without this fix the test passed incidentally but didn't exercise
the sticky-break logic.
@rafabene
Copy link
Copy Markdown
Contributor Author

rafabene commented May 8, 2026

Thanks for catching these!

  1. aggregation_test.go — Good catch. Fixed in commit 90028f8. The test was using ConditionTypeAvailable in prevConds but parsePrevConditions looks for ConditionTypeLastKnownReconciled, so the sticky-break logic wasn't being exercised properly.

  2. openapi/openapi.yaml (minItems: 3) — This file is synced from the upstream hyperfleet-api-spec repository and must not be edited directly here. I'll raise this as an issue upstream.

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
pkg/services/aggregation_test.go (1)

89-101: 🧹 Nitpick | 🔵 Trivial | 💤 Low value

Consider renaming mkPrevAvail to match its actual behavior.

The helper function name mkPrevAvail suggests it creates an "Available" condition, but it now creates a LastKnownReconciled condition (line 94). Consider renaming to mkPrevLastKnownReconciled or mkPrevLKR for consistency.

♻️ Suggested rename
-// mkPrevAvail builds a LastKnownReconciled ResourceCondition for use as a prev fixture.
-func mkPrevAvail(
+// mkPrevLastKnownReconciled builds a LastKnownReconciled ResourceCondition for use as a prev fixture.
+func mkPrevLastKnownReconciled(
 	status api.ResourceConditionStatus, obsGen int32, lastTransition, lastUpdated time.Time,
 ) *api.ResourceCondition {

Then update all call sites accordingly (lines 730, 759, 792, 889, 920, 935, 979, 993, 1004).

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@pkg/services/aggregation_test.go` around lines 89 - 101, Rename the helper
mkPrevAvail to a name that reflects it builds a LastKnownReconciled condition
(suggested mkPrevLastKnownReconciled or mkPrevLKR) and update all call sites
that reference mkPrevAvail (occurrences near the tests around lines with uses at
roughly the blocks referenced: callers at the locations noted in the review) to
use the new name; ensure the function signature and returned
api.ResourceCondition remain unchanged so tests compile, and update any
comments/docstrings to match the new name (function identifier: mkPrevAvail ->
mkPrevLastKnownReconciled or mkPrevLKR).
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Outside diff comments:
In `@pkg/services/aggregation_test.go`:
- Around line 89-101: Rename the helper mkPrevAvail to a name that reflects it
builds a LastKnownReconciled condition (suggested mkPrevLastKnownReconciled or
mkPrevLKR) and update all call sites that reference mkPrevAvail (occurrences
near the tests around lines with uses at roughly the blocks referenced: callers
at the locations noted in the review) to use the new name; ensure the function
signature and returned api.ResourceCondition remain unchanged so tests compile,
and update any comments/docstrings to match the new name (function identifier:
mkPrevAvail -> mkPrevLastKnownReconciled or mkPrevLKR).

ℹ️ Review info
⚙️ Run configuration

Configuration used: Central YAML (base), Organization UI (inherited)

Review profile: ASSERTIVE

Plan: Enterprise

Run ID: 37fe71fe-2273-4a49-896b-93e2ba736815

📥 Commits

Reviewing files that changed from the base of the PR and between f08a379 and 90028f8.

📒 Files selected for processing (1)
  • pkg/services/aggregation_test.go

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.

2 participants