A re-check against the code found four mismatches: the kvm connection is opened at startup by the leader's first health check, so that isn't doc drift; cmd/main.go, not the monitor, type-asserts Checker; QuotaExceeded and PermanentError are reasons on Provisioned, not conditions; and the latch line range. The checklist also now matches how the existing providers do interface assertions and RBAC markers. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
4.4 KiB
Execution: provider blueprint
Plan: docs/plans/2026-09-16-0841-provider-blueprint.md
- Step 0 — Save the plan; wait for the merge
- Step 1 — Collect evidence (read-only, in parallel)
- Step 2 — Write
docs/providers.md - Step 3 — Verify, then open the MR
Step 0 — Save the plan; wait for the merge
The plan was committed on feat/provider-health (80b2e9c) and reached main
through PR #6. After the user confirmed the merge, the branch was cut from the
updated main:
git switch main && git pull --ff-only
git switch -c feat/provider-blueprint
Worth noting: .claude/settings.json has local, uncommitted permission edits
that carried over through the switch. They are deliberately left out of this
branch.
Step 1 — Collect evidence (read-only, in parallel)
Three Explore agents answered the plan's 12-item questionnaire, one each for
kubernetes, gcp and kvm. Meanwhile I read the shared layer:
internal/provider/*.go, registry.go, the provider wiring in cmd/main.go,
reconcileManaged/replaceInstance/reconcileDelete in the controller,
internal/gc/gc.go, and how the monitor uses Checker.
Before relying on the agents' claims, I spot-checked them against the code. One
was wrong and did not go into the doc: the kvm agent said Delete skips volume
removal when DomainDestroy returns ErrNoDomain. In fact removeDomain
returns nil there, and Delete still calls removeVolumes afterwards
(kvm.go:477-482).
Rules that exist only in the callers, and not in any comment, were found by reading the controller and GC. They went into the doc as MUST rules:
- A zero
CreatedAtmakes an instance immediately collectable (gc.go:120). GetreturningErrPermanenton the deletion path makes the reconciler callDeleteanyway.- Replacement waits for
Getto return NotFound before creating an instance with the same name. StoppedandTerminatedboth lead to delete-and-recreate.
Worth noting, found outside this plan's scope and not changed here:
docs/gcp-vm-validation.mdfilters onlabels.proxy-operator-managed=yes, but the value istrue.- According to the gcp agent,
docs/gcp-in-specific-project.mdholds a real project ID, IAM output and an egress IP. The user was told.
Step 2 — Write docs/providers.md
Wrote the eight sections the plan lists. Linked the new doc from the Provider
contract row in docs/architecture.md and from the CLAUDE.md "Architecture"
section.
Judgment calls:
- The file:line evidence sits in per-provider notes under the matrix, as planned. The contract rules in §2 cite the reconciler and GC lines each rule protects.
- The gap list includes documentation drift (kvm-provider.md's ARP order and log keys, gcp-vm-validation.md's label value and its claim that async errors reach status), as well as code gaps. Both would mislead the next provider author in the same way.
- "Proposed features" stays a flat list with no design, as the user decided.
Worth noting: the line numbers in the doc are a snapshot. The doc says so and asks readers to look for the named function when a line has moved.
Step 3 — Verify, then open the MR
An Explore agent re-checked the doc against the code: about 150 claims, including every matrix cell. It found four mismatches, and all four were fixed:
- Startup dial: I had listed kvm-provider.md's "connection kept open from
startup" as doc drift. It isn't: the pool dials lazily, but the provider
health monitor runs a check as soon as the leader starts
(
monitor.go:147, default interval 1m), and that check opens the connection. The bullet was removed and the kvm notes now say this. - Checker wording: §5 said the monitor type-asserts
Checker. It iscmd/main.go:216; the monitor only sees nil or not. - Reasons, not conditions: §3 called
QuotaExceededandPermanentErrorconditions. They are reasons onProvisioned. - Latch lines: the line range is
:133-139, not:130-135.
It also noted that none of the providers assert var _ provider.Provider, and
that the kubernetes provider's RBAC markers live in the controller package. The
§7 checklist now says both.
Link check (every relative ](…) target and anchor in the new and edited docs
resolves), then the sanity build:
go build ./... && go test -short ./...
# all packages ok
Worth noting: no CHANGELOG entry yet. Per CLAUDE.md it goes in after the user confirms the doc.