Skip to content

fix(repositories): keep org-enforced signoff out of update payloads - #127

Merged
devantler merged 6 commits into
mainfrom
claude/repository-signoff-initprovider-112
Jul 27, 2026
Merged

fix(repositories): keep org-enforced signoff out of update payloads#127
devantler merged 6 commits into
mainfrom
claude/repository-signoff-initprovider-112

Conversation

@devantler

@devantler devantler commented Jul 27, 2026

Copy link
Copy Markdown
Contributor

🤖 Generated by the Agentic Engineer

Why

None of the repository settings we declare in this repo could actually reach GitHub for any repo that
had something to apply. GitHub rejects an entire repository update when it mentions the commit-signoff
setting the organization already enforces, and our shared config put that setting into every update.

The visible cost: agent-plugins and agent-skills each declare a list of topics so people can find
them, and both still show no topics at all on GitHub. Two public products have been invisible to
topic-based browsing since the day those topics were declared.

What

Applies the enforced signoff default only when a repository is created, so new repos still get it
while existing repos become updatable again. A new check runs in CI so this cannot silently come back.

Restoring the update path also means the config finally acts on what it declares — including two repos
that declare themselves private while being live and public with a deployed site
(ascoachingogvaner, wedding-app). Both are parked read-only here so that cannot happen as a side
effect; which side is wrong is your call, tracked on #123.

No repository loses the signoff protection, and deletion stays impossible as before.

Design and diagnosis come from #120; this is that change rebased onto current main, which it had
conflicted with since #125.

Fixes #112

The org enforces web commit signoff, and GitHub rejects an entire repository
PATCH with 422 whenever web_commit_signoff_required appears in it, whatever
value the field carries. The shared patch pinned it into forProvider, which is
exactly the payload every update sends, so no declared setting could reach
GitHub for any repository that had a pending diff.

Move it to initProvider, which Crossplane applies only at creation, and drop
LateInitialize from the active management policy so live-only values stop
leaking back into forProvider and re-poisoning later updates.

tests/repository-update-policy.sh pins all three invariants and runs in CI.

Design and diagnosis from #120 (codex lane), rebased onto current main.
ascoachingogvaner and wedding-app declare `visibility: private` while both live
repositories are public, and both host a deployed site. Restoring the update
path would otherwise make the reconciler act on that declaration and turn two
live public sites private, as a side effect of an unrelated fix.

Park both on Observe until #123 settles which side is wrong. The update-policy
test now pins the actual hazards — no LateInitialize, no Delete — instead of an
exact policy cardinality, so a read-only repository satisfies it by construction.
…ally

Replacing managementPolicies in the shared patch would have overridden every
repository's own policy, promoting world-at-ruin from its deliberate Observe-only
state and defeating the Observe-first adoption ladder for any repo added later.

Remove LateInitialize from each Repository resource instead, leaving each repo's
position on that ladder under its own file. DefaultBranch resources keep their
policy; they are a different API and are not affected by the signoff rejection.

ascoachingogvaner and wedding-app drop to Observe in their own files rather than
through a name-matched exception patch.
The per-repo comments described LateInitialize adopting settings on every
reconcile, which is no longer what happens. State the current contract instead:
the shared patch supplies the org-wide merge policy, the file supplies what it
declares, and anything in neither keeps the value adopted at first observation.
@devantler

Copy link
Copy Markdown
Contributor Author

🤖 Generated by the Agentic Engineer

@coderabbitai review

@devantler

Copy link
Copy Markdown
Contributor Author

🤖 Generated by the Agentic Engineer

@codex review

@coderabbitai

coderabbitai Bot commented Jul 27, 2026

Copy link
Copy Markdown

@devantler: I’ll review the changes.

✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@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: 99fc268f6d

ℹ️ 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 tests/repository-update-policy.sh Outdated
Comment thread deploy/repositories/kustomization.yaml Outdated
@coderabbitai

coderabbitai Bot commented Jul 27, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

Repository manifests remove LateInitialize from active management policies, with selected repositories changed to observe-only. The shared Kustomize patch places webCommitSignoffRequired in initProvider and pins hasDownloads. A validation script checks rendered repository policies and field placement, and CI runs it during manifest validation. AGENTS.md documents the updated Crossplane and validation rules.

Possibly related PRs

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% 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
Linked Issues check ✅ Passed The changes match #112 by moving signoff to initProvider, removing unsafe late-init update behavior, and adding CI coverage.
Out of Scope Changes check ✅ Passed The changed files stay focused on repository management policy, kustomization, validation, and related docs/comments.
Title check ✅ Passed The title clearly matches the main change: keeping org-enforced signoff out of repository update payloads.
Description check ✅ Passed The description is on-topic and describes the signoff fix, CI guard, and related repository behavior changes.

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

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

@coderabbitai coderabbitai 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.

Actionable comments posted: 1

🤖 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 `@deploy/repositories/agent-plugins.yaml`:
- Around line 14-15: Clarify the repeated comments describing omitted repository
settings as unmanaged rather than implying Crossplane adopts or manages live
values. Update the wording at deploy/repositories/agent-plugins.yaml lines
14-15, deploy/repositories/agent-skills.yaml lines 15-16,
deploy/repositories/doggy-countdown.yaml lines 11-13,
deploy/repositories/dotnet-template.yaml lines 8-12,
deploy/repositories/fleet-gitops.yaml lines 8-13,
deploy/repositories/gitops-tenant-template.yaml lines 8-12,
deploy/repositories/go-template.yaml lines 8-12,
deploy/repositories/homebrew-tap.yaml lines 8-12, and
deploy/repositories/ksail.yaml lines 10-15 to state that settings absent from
both forProvider and the shared patch remain observed from live state without
being copied into or managed by the spec.

ℹ️ Review info
⚙️ Run configuration

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

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: cdf5e835-06f9-4a0c-b90e-844bf8c7e35d

📥 Commits

Reviewing files that changed from the base of the PR and between 696dbb2 and 99fc268.

📒 Files selected for processing (22)
  • .github/workflows/ci.yaml
  • AGENTS.md
  • deploy/repositories/agent-plugins.yaml
  • deploy/repositories/agent-skills.yaml
  • deploy/repositories/ascoachingogvaner.yaml
  • deploy/repositories/aws.yaml
  • deploy/repositories/doggy-countdown.yaml
  • deploy/repositories/dotnet-template.yaml
  • deploy/repositories/fleet-gitops.yaml
  • deploy/repositories/gitops-tenant-template.yaml
  • deploy/repositories/go-template.yaml
  • deploy/repositories/homebrew-tap.yaml
  • deploy/repositories/ksail.yaml
  • deploy/repositories/kustomization.yaml
  • deploy/repositories/kyverno-policies.yaml
  • deploy/repositories/maintenance.yaml
  • deploy/repositories/platform-template.yaml
  • deploy/repositories/platform.yaml
  • deploy/repositories/provider-upjet-unifi.yaml
  • deploy/repositories/unifi.yaml
  • deploy/repositories/wedding-app.yaml
  • tests/repository-update-policy.sh
💤 Files with no reviewable changes (3)
  • deploy/repositories/provider-upjet-unifi.yaml
  • deploy/repositories/kyverno-policies.yaml
  • deploy/repositories/aws.yaml
📜 Review details
🧰 Additional context used
📓 Path-based instructions (5)
deploy/**/*.{yaml,yml}

📄 CodeRabbit inference engine (AGENTS.md)

deploy/**/*.{yaml,yml}: Manage GitHub organization, repository, team, and label configuration declaratively by editing deploy/ and shipping a PR; never write managed configuration through the GitHub UI or gh api. Reading is allowed, and applying an existing label is triage rather than configuration.
When adopting an existing GitHub resource, set crossplane.io/external-name to the live name and use a management policy that excludes Delete to prevent recreation or deletion.
Verify every Crossplane kind and field against the authoritative provider CRDs and generated examples; local schema validation is unavailable.
Preserve the documented deploy/ layout: repositories, teams, team memberships, team-repositories, labels, provider configuration, external secret, and top-level kustomization belong in their designated paths.
Ensure the top-level deploy/kustomization.yaml wires all deployment resources and the shared repository-settings patch.
Before every PR, run kubectl kustomize deploy/, bash tests/admin-team-policy.sh, bash tests/declarative-coverage.sh, and bash tests/repository-update-policy.sh; all must pass.
Crossplane CRs must be schema-checked against the provider’s published CRDs because CI only runs kubectl kustomize and does not validate CRDs locally.

Files:

  • deploy/repositories/ksail.yaml
  • deploy/repositories/platform-template.yaml
  • deploy/repositories/unifi.yaml
  • deploy/repositories/go-template.yaml
  • deploy/repositories/fleet-gitops.yaml
  • deploy/repositories/dotnet-template.yaml
  • deploy/repositories/gitops-tenant-template.yaml
  • deploy/repositories/doggy-countdown.yaml
  • deploy/repositories/agent-plugins.yaml
  • deploy/repositories/ascoachingogvaner.yaml
  • deploy/repositories/wedding-app.yaml
  • deploy/repositories/homebrew-tap.yaml
  • deploy/repositories/agent-skills.yaml
  • deploy/repositories/platform.yaml
  • deploy/repositories/kustomization.yaml
  • deploy/repositories/maintenance.yaml
deploy/repositories/**/*.{yaml,yml}

📄 CodeRabbit inference engine (AGENTS.md)

deploy/repositories/**/*.{yaml,yml}: For an adopted active Repository, use Observe/Create/Update without LateInitialize; keep late-initialized values out of subsequent update payloads.
Put org-enforced creation defaults such as webCommitSignoffRequired in initProvider, not forProvider, because GitHub rejects that field in update PATCH requests.

Files:

  • deploy/repositories/ksail.yaml
  • deploy/repositories/platform-template.yaml
  • deploy/repositories/unifi.yaml
  • deploy/repositories/go-template.yaml
  • deploy/repositories/fleet-gitops.yaml
  • deploy/repositories/dotnet-template.yaml
  • deploy/repositories/gitops-tenant-template.yaml
  • deploy/repositories/doggy-countdown.yaml
  • deploy/repositories/agent-plugins.yaml
  • deploy/repositories/ascoachingogvaner.yaml
  • deploy/repositories/wedding-app.yaml
  • deploy/repositories/homebrew-tap.yaml
  • deploy/repositories/agent-skills.yaml
  • deploy/repositories/platform.yaml
  • deploy/repositories/kustomization.yaml
  • deploy/repositories/maintenance.yaml
.github/workflows/ci.yaml

📄 CodeRabbit inference engine (AGENTS.md)

The CI workflow must provide the PR-time CI - Required Checks gate using the four mandated validation commands.

Files:

  • .github/workflows/ci.yaml
AGENTS.md

📄 CodeRabbit inference engine (CLAUDE.md)

Follow the instructions defined in AGENTS.md.

Files:

  • AGENTS.md
**/AGENTS.md

📄 CodeRabbit inference engine (GEMINI.md)

Follow the coding guidelines and instructions defined in AGENTS.md.

Keep this repository’s AGENTS.md synchronized with the actual deploy/ layout and shared engineering contract; do not add a redundant .github/copilot-instructions.md.

Files:

  • AGENTS.md
🧠 Learnings (2)
📓 Common learnings
Learnt from: CR
Repo: devantler-tech/.github

Timestamp: 2026-07-27T08:39:36.686Z
Learning: Use GitHub Issues as the roadmap of record; triage incoming work into the epic and roadmap-labelled children, and use `Fixes `#N`` in implementing PRs.
Learnt from: CR
Repo: devantler-tech/.github

Timestamp: 2026-07-27T08:39:36.686Z
Learning: Bring newly discovered repositories or out-of-band organization, repository, or team changes under declarative management through Observe-first roadmap/enhancement work, never by applying a UI fix.
📚 Learning: 2026-07-10T14:42:56.622Z
Learnt from: devantler
Repo: devantler-tech/.github PR: 90
File: deploy/archived-repositories/kustomization.yaml:11-16
Timestamp: 2026-07-10T14:42:56.622Z
Learning: In this repo’s deployment setup, `deploy/` kustomize manifests are rendered unconditionally (no feature-flag/conditional-render/apply primitive) and Flux applies from `main`. For irreversible or ordering-sensitive rollouts in `deploy/` (e.g., changes under `deploy/archived-repositories/` that require prerequisites handled in separate PRs), reviewers should not expect a mechanical CI guard. Instead, require the PR to remain in draft until the required prerequisite one-click actions (e.g., org `required-workflow` ruleset repointing) are completed, with the required rollout ordering explicitly documented in the PR body (per the documented bold line). Only then should the PR be promoted/merged.

Applied to files:

  • deploy/repositories/kustomization.yaml
🪛 LanguageTool
AGENTS.md

[style] ~90-~90: Consider an alternative for the overused word “exactly”.
Context: ...invariants ``` Those four commands are exactly what ci.yaml runs. `kubectl` (with b...

(EXACTLY_PRECISELY)

🔇 Additional comments (11)
deploy/repositories/ascoachingogvaner.yaml (1)

8-16: LGTM!

deploy/repositories/maintenance.yaml (1)

1-6: LGTM!

Also applies to: 14-17

deploy/repositories/platform-template.yaml (1)

8-16: LGTM!

deploy/repositories/platform.yaml (1)

10-19: LGTM!

deploy/repositories/unifi.yaml (1)

8-16: LGTM!

deploy/repositories/wedding-app.yaml (1)

8-16: LGTM!

deploy/repositories/kustomization.yaml (2)

4-14: LGTM!


60-85: 📐 Maintainability & Code Quality

Schema-check the Repository initProvider.webCommitSignoffRequired path before merge.

This repository does not declare the provider-upjet-github package version or store the published CRD, but the code comment describes webCommitSignoffRequired as create-only to avoid GitHub 422 updates. Confirm the installed provider’s repo.github.m.upbound.io/Repository CRD and generated example expose spec.initProvider.webCommitSignoffRequired; otherwise this shared patch can add an unknown/unsupported field into deploy configs.

tests/repository-update-policy.sh (1)

1-86: LGTM!

.github/workflows/ci.yaml (1)

38-39: LGTM!

AGENTS.md (1)

44-49: LGTM!

Also applies to: 87-90

Comment thread deploy/repositories/agent-plugins.yaml
Two review findings, both real.

The update-policy check rejected LateInitialize outright, which fails CI for a
repository sitting in this repo's own documented Observe-first adoption phase —
Observe+LateInitialize sends no update, so it cannot produce a bad payload. The
hazard is pairing LateInitialize with Update; assert that instead.

The shared initProvider seed was a JSON Patch `add` on the map itself, which
replaces it wholesale and would silently drop any create-only setting a
repository declared for itself. Use a merge patch, which creates the map when
absent and merges into it when present.

Also states what an undeclared setting actually does now: it is unmanaged,
rather than re-adopted on every reconcile.
@devantler

Copy link
Copy Markdown
Contributor Author

🤖 Generated by the Agentic Engineer

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Jul 27, 2026

Copy link
Copy Markdown

@devantler: I’ll review the changes.

✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@coderabbitai coderabbitai 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.

Actionable comments posted: 1

🤖 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 `@deploy/repositories/doggy-countdown.yaml`:
- Around line 12-14: Clarify the comments describing post-LateInitialize
behavior: newly observed undeclared fields are unmanaged, while fields
late-initialized before this change may remain in spec.forProvider as
provider-owned values and continue reaching update payloads. Apply this explicit
legacy-behavior wording at deploy/repositories/doggy-countdown.yaml lines 12-14,
deploy/repositories/dotnet-template.yaml lines 11-13,
deploy/repositories/fleet-gitops.yaml lines 12-14,
deploy/repositories/go-template.yaml lines 11-13,
deploy/repositories/homebrew-tap.yaml lines 10-12,
deploy/repositories/platform-template.yaml lines 11-13,
deploy/repositories/platform.yaml lines 14-16, and
deploy/repositories/unifi.yaml lines 11-13.

ℹ️ Review info
⚙️ Run configuration

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

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 9657d79c-4048-4044-ab7b-be5a33af3e1c

📥 Commits

Reviewing files that changed from the base of the PR and between 99fc268 and 0fe8466.

📒 Files selected for processing (11)
  • deploy/repositories/doggy-countdown.yaml
  • deploy/repositories/dotnet-template.yaml
  • deploy/repositories/fleet-gitops.yaml
  • deploy/repositories/gitops-tenant-template.yaml
  • deploy/repositories/go-template.yaml
  • deploy/repositories/homebrew-tap.yaml
  • deploy/repositories/kustomization.yaml
  • deploy/repositories/platform-template.yaml
  • deploy/repositories/platform.yaml
  • deploy/repositories/unifi.yaml
  • tests/repository-update-policy.sh
📜 Review details
🧰 Additional context used
📓 Path-based instructions (4)
deploy/**/*.{yaml,yml}

📄 CodeRabbit inference engine (AGENTS.md)

deploy/**/*.{yaml,yml}: Manage GitHub organization, repository, team, and label configuration declaratively by editing deploy/ and shipping a PR; never write managed configuration through gh api or the GitHub UI.
Verify every new Crossplane resource's kind and field schema against the authoritative provider CRDs and generated examples; local schema validation is unavailable.

Files:

  • deploy/repositories/dotnet-template.yaml
  • deploy/repositories/platform.yaml
  • deploy/repositories/go-template.yaml
  • deploy/repositories/doggy-countdown.yaml
  • deploy/repositories/gitops-tenant-template.yaml
  • deploy/repositories/platform-template.yaml
  • deploy/repositories/fleet-gitops.yaml
  • deploy/repositories/unifi.yaml
  • deploy/repositories/homebrew-tap.yaml
  • deploy/repositories/kustomization.yaml
deploy/{repositories,teams,labels}/**/*.{yaml,yml}

📄 CodeRabbit inference engine (AGENTS.md)

When adopting an existing repository, issue-label set, or team, use the live name in the crossplane.io/external-name annotation and a management policy excluding Delete to observe/late-initialize without recreate or deletion.

Files:

  • deploy/repositories/dotnet-template.yaml
  • deploy/repositories/platform.yaml
  • deploy/repositories/go-template.yaml
  • deploy/repositories/doggy-countdown.yaml
  • deploy/repositories/gitops-tenant-template.yaml
  • deploy/repositories/platform-template.yaml
  • deploy/repositories/fleet-gitops.yaml
  • deploy/repositories/unifi.yaml
  • deploy/repositories/homebrew-tap.yaml
  • deploy/repositories/kustomization.yaml
deploy/repositories/*.yaml

📄 CodeRabbit inference engine (AGENTS.md)

deploy/repositories/*.yaml: After adopting a Repository, use Observe/Create/Update without LateInitialize; keep late-initialized values in forProvider, and put create-only defaults such as webCommitSignoffRequired in initProvider so they are not sent in update PATCH requests.
Define one Repository resource per managed repository file.

Files:

  • deploy/repositories/dotnet-template.yaml
  • deploy/repositories/platform.yaml
  • deploy/repositories/go-template.yaml
  • deploy/repositories/doggy-countdown.yaml
  • deploy/repositories/gitops-tenant-template.yaml
  • deploy/repositories/platform-template.yaml
  • deploy/repositories/fleet-gitops.yaml
  • deploy/repositories/unifi.yaml
  • deploy/repositories/homebrew-tap.yaml
  • deploy/repositories/kustomization.yaml
tests/*.sh

📄 CodeRabbit inference engine (AGENTS.md)

Before every PR, run the required validation commands: kubectl kustomize deploy/, bash tests/admin-team-policy.sh, bash tests/declarative-coverage.sh, and bash tests/repository-update-policy.sh.

Files:

  • tests/repository-update-policy.sh
🧠 Learnings (3)
📓 Common learnings
Learnt from: CR
Repo: devantler-tech/.github

Timestamp: 2026-07-27T11:39:43.726Z
Learning: Use GitHub Issues as the roadmap of record; triage incoming issues into epic `#56` and its `roadmap`-labelled children, and use `Fixes `#N`` in implementing pull requests.
Learnt from: CR
Repo: devantler-tech/.github

Timestamp: 2026-07-27T11:39:43.726Z
Learning: When adopting existing GitHub resources or responding to drift, use an Observe-first declarative change in `deploy/`; never fix managed drift directly through the GitHub UI or imperative API writes.
📚 Learning: 2026-07-27T11:40:06.755Z
Learnt from: devantler
Repo: devantler-tech/.github PR: 127
File: deploy/repositories/agent-plugins.yaml:14-15
Timestamp: 2026-07-27T11:40:06.755Z
Learning: When reviewing Crossplane GitHub `Repository` resources under `deploy/repositories/*.yaml`, note that removing `LateInitialize` prevents newly observed/undeclared fields from being copied into `spec.forProvider`. As a result, those newly added settings become unmanaged until explicitly declared. However, fields that were late-initialized before this policy change may already exist in `spec.forProvider`; they are then owned by the provider field manager (not Flux `kustomize-controller`) and may remain in provider update payloads. Require comments to clearly distinguish these two cases so reviewers know whether a field is newly unmanaged vs. pre-existing provider-owned data.

Applied to files:

  • deploy/repositories/dotnet-template.yaml
  • deploy/repositories/platform.yaml
  • deploy/repositories/go-template.yaml
  • deploy/repositories/doggy-countdown.yaml
  • deploy/repositories/gitops-tenant-template.yaml
  • deploy/repositories/platform-template.yaml
  • deploy/repositories/fleet-gitops.yaml
  • deploy/repositories/unifi.yaml
  • deploy/repositories/homebrew-tap.yaml
  • deploy/repositories/kustomization.yaml
📚 Learning: 2026-07-10T14:42:56.622Z
Learnt from: devantler
Repo: devantler-tech/.github PR: 90
File: deploy/archived-repositories/kustomization.yaml:11-16
Timestamp: 2026-07-10T14:42:56.622Z
Learning: In this repo’s deployment setup, `deploy/` kustomize manifests are rendered unconditionally (no feature-flag/conditional-render/apply primitive) and Flux applies from `main`. For irreversible or ordering-sensitive rollouts in `deploy/` (e.g., changes under `deploy/archived-repositories/` that require prerequisites handled in separate PRs), reviewers should not expect a mechanical CI guard. Instead, require the PR to remain in draft until the required prerequisite one-click actions (e.g., org `required-workflow` ruleset repointing) are completed, with the required rollout ordering explicitly documented in the PR body (per the documented bold line). Only then should the PR be promoted/merged.

Applied to files:

  • deploy/repositories/kustomization.yaml
🔇 Additional comments (1)
deploy/repositories/gitops-tenant-template.yaml (1)

8-17: LGTM!

Comment on lines +12 to +14
# config is AUTHORITATIVE for it. Settings in neither
# are unmanaged: nothing new is copied into the spec, and values adopted
# earlier stay.

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

Clarify the legacy late-initialized-field behavior.

“Values adopted earlier stay” obscures the material distinction: newly observed undeclared fields are unmanaged, while fields late-initialized before this change may already remain in spec.forProvider, be provider-owned, and still reach update payloads.

  • deploy/repositories/doggy-countdown.yaml#L12-L14: state the legacy provider-owned-field behavior explicitly.
  • deploy/repositories/dotnet-template.yaml#L11-L13: state the legacy provider-owned-field behavior explicitly.
  • deploy/repositories/fleet-gitops.yaml#L12-L14: state the legacy provider-owned-field behavior explicitly.
  • deploy/repositories/go-template.yaml#L11-L13: state the legacy provider-owned-field behavior explicitly.
  • deploy/repositories/homebrew-tap.yaml#L10-L12: state the legacy provider-owned-field behavior explicitly.
  • deploy/repositories/platform-template.yaml#L11-L13: state the legacy provider-owned-field behavior explicitly.
  • deploy/repositories/platform.yaml#L14-L16: state the legacy provider-owned-field behavior explicitly.
  • deploy/repositories/unifi.yaml#L11-L13: state the legacy provider-owned-field behavior explicitly.

Based on learnings: removal of LateInitialize affects newly observed fields differently from previously provider-owned values.

📍 Affects 8 files
  • deploy/repositories/doggy-countdown.yaml#L12-L14 (this comment)
  • deploy/repositories/dotnet-template.yaml#L11-L13
  • deploy/repositories/fleet-gitops.yaml#L12-L14
  • deploy/repositories/go-template.yaml#L11-L13
  • deploy/repositories/homebrew-tap.yaml#L10-L12
  • deploy/repositories/platform-template.yaml#L11-L13
  • deploy/repositories/platform.yaml#L14-L16
  • deploy/repositories/unifi.yaml#L11-L13
🤖 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 `@deploy/repositories/doggy-countdown.yaml` around lines 12 - 14, Clarify the
comments describing post-LateInitialize behavior: newly observed undeclared
fields are unmanaged, while fields late-initialized before this change may
remain in spec.forProvider as provider-owned values and continue reaching update
payloads. Apply this explicit legacy-behavior wording at
deploy/repositories/doggy-countdown.yaml lines 12-14,
deploy/repositories/dotnet-template.yaml lines 11-13,
deploy/repositories/fleet-gitops.yaml lines 12-14,
deploy/repositories/go-template.yaml lines 11-13,
deploy/repositories/homebrew-tap.yaml lines 10-12,
deploy/repositories/platform-template.yaml lines 11-13,
deploy/repositories/platform.yaml lines 14-16, and
deploy/repositories/unifi.yaml lines 11-13.

Source: Learnings

@devantler

Copy link
Copy Markdown
Contributor Author

🤖 Generated by the Agentic Engineer

Readiness evidence at 0fe84663.

Programmatically tested. tests/repository-update-policy.sh added and wired into CI. Each of its
three guards RED-proven independently by ablation, and each restored byte-identically afterwards:
signoff back in forProvider → caught; the initProvider seed removed → caught; Update paired with
LateInitialize → caught; adoption-phase [Observe, LateInitialize] → correctly passes; Delete
caught. Full suite green (kubectl kustomize, admin-team-policy, declarative-coverage,
repository-update-policy); all CI checks green.

Reviewed. Codex and CodeRabbit both reviewed; three findings, all fixed and their threads resolved.
CodeRabbit re-reviewed at this head with no findings and no open threads.

Tried and evaluated as a user. The mechanism this fix depends on is that Flux's server-side apply
drops a field once the manifest stops declaring it. Verified against the live cluster with a
non-mutating server-side dry-run using Flux's own field manager:

spec.forProvider.webCommitSignoffRequired   true  ->  ABSENT   # no longer in the update payload
spec.initProvider.webCommitSignoffRequired         true        # create-only default preserved
spec.forProvider.topics                            10          # the diff that could never be delivered
spec.forProvider.hasWiki                           true        # previously-adopted value preserved

That is the whole intended state transition, observed rather than reasoned about. Also confirmed the
live CRD accepts the rendered resources, and that the merge patch preserves a repository-specific
initProvider key (added autoInit to one manifest and rendered: both keys survive; under the
previous JSON Patch add the repo-specific key was dropped).

What is not yet proven, and cannot be pre-merge: that topics actually appear on GitHub. That needs
the change deployed and a reconcile. I will verify it against the GitHub API after merge and report on
#123.

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.

fix: declarative repo-settings updates are write-blocked (422 on every update PATCH)

1 participant