Provider docs: generic contract, spec template and appendix on the existing providers #7

Merged
kacerr merged 11 commits from feat/provider-blueprint into main 2026-09-16 13:48:40 +02:00
Owner

Documentation only; no code changes.

The branch first added a single-file provider blueprint (docs/providers.md, first four commits), then split it so that a new provider can be specified and built from generic rules alone. The split supersedes the blueprint; docs/providers.md is now an index.

The files

  • docs/provider-contract.md: what every provider MUST, SHOULD and MAY do. Every MUST names the caller function (reconcileManaged, replaceInstance, reconcileDelete, Sweeper.sweep, Monitor.checkOnce, ...) and what breaks. §4 defines 19 behaviour-profile axes with stable codes (readiness, create-return, provisioning-state, primary-key, async-ops, gc-mark, list-partial, ...), each with the allowed profiles and what the callers tolerate, so "a pod is ready at once, a VM has a provisioning window, one provider blocks in Create and another does not" is stated as a rule rather than discovered from code. Also: error taxonomy, identity and marks, credential and TLS hygiene, the Checker, observability, config wiring, testing obligations, the checklist for adding a provider, and the contract's known limits. It never names kubernetes, gcp or kvm (enforced by grep).
  • docs/provider-spec-template.md: 24 fill-in entries (Question, Allowed answers, Obligations, Answer, Evidence), one per decision the contract leaves to the provider: identity, primary key, placement, image source, cloud-init delivery, IP discovery, GC marks, state mapping, Create/Delete semantics, errors, credentials, config block, Checker, client and spans, timeouts, concurrency, logging, tests, deployment, docs, accepted limits. Entry numbers match the contract's §4.20 table; entry 21 carries the contract's test list as checkboxes. Copy to docs/<type>-provider-spec.md and fill in before implementing.
  • docs/providers-existing.md: the appendix. One table with a row per axis code showing each existing provider's profile and the symbol proving it, then reference sections for kubernetes, gcp and kvm (seam, config, ID, Create, state-mapping table, IP source, Delete, ListByTag, classify table, Check, logging, tracing, tests, deployment, known gaps), shared gaps, and the proposed-features list.
  • docs/providers.md: the index. README "Adding a provider", CLAUDE.md and the architecture.md components row point at the new files.

Two rules the old blueprint did not have

Both found by reading the callers while verifying:

  • No caller puts a deadline on the context, and Sweeper.sweep loops providers sequentially, so one hung ListByTag stalls orphan GC for every provider. Now §1.5 and the timeouts axis.
  • The Stopped branch of reconcileManaged deletes and requeues without clearing ProviderID, so a backend that reports a freshly created, never started instance as stopped would have it deleted right after creation. Now a MUST in §2.2 and the provisioning-state axis (native, create-blocks, marker).

Conventions

  • Code references are path plus symbol, never line numbers (the blueprint's file:line references had already drifted).
  • No em-dashes in the new files.

Verification

Recorded in docs/plans-executions/2026-09-16-1108-provider-docs-split.md: every relative link and anchor across the four new files plus README, CLAUDE.md and architecture.md resolves (script in the log); no em-dashes or line references in the new files; the contract contains none of kubernetes/gcp/kvm/libvirt/squid/google; every old §9 gap and proposal topic is present in the new files; every cited path and symbol exists; the 19 axis codes each appear once in the appendix table and in the template; go build ./... && go test -short ./... pass.

Plans: docs/plans/2026-09-16-0841-provider-blueprint.md (blueprint) and docs/plans/2026-09-16-1108-provider-docs-split.md (split), with paired execution logs.

🤖 Generated with Claude Code

Documentation only; no code changes. The branch first added a single-file provider blueprint (`docs/providers.md`, first four commits), then split it so that a new provider can be specified and built from generic rules alone. The split supersedes the blueprint; `docs/providers.md` is now an index. ## The files - **`docs/provider-contract.md`**: what every provider MUST, SHOULD and MAY do. Every MUST names the caller function (`reconcileManaged`, `replaceInstance`, `reconcileDelete`, `Sweeper.sweep`, `Monitor.checkOnce`, ...) and what breaks. §4 defines 19 behaviour-profile axes with stable codes (`readiness`, `create-return`, `provisioning-state`, `primary-key`, `async-ops`, `gc-mark`, `list-partial`, ...), each with the allowed profiles and what the callers tolerate, so "a pod is ready at once, a VM has a provisioning window, one provider blocks in Create and another does not" is stated as a rule rather than discovered from code. Also: error taxonomy, identity and marks, credential and TLS hygiene, the `Checker`, observability, config wiring, testing obligations, the checklist for adding a provider, and the contract's known limits. It never names kubernetes, gcp or kvm (enforced by grep). - **`docs/provider-spec-template.md`**: 24 fill-in entries (Question, Allowed answers, Obligations, Answer, Evidence), one per decision the contract leaves to the provider: identity, primary key, placement, image source, cloud-init delivery, IP discovery, GC marks, state mapping, Create/Delete semantics, errors, credentials, config block, Checker, client and spans, timeouts, concurrency, logging, tests, deployment, docs, accepted limits. Entry numbers match the contract's §4.20 table; entry 21 carries the contract's test list as checkboxes. Copy to `docs/<type>-provider-spec.md` and fill in before implementing. - **`docs/providers-existing.md`**: the appendix. One table with a row per axis code showing each existing provider's profile and the symbol proving it, then reference sections for kubernetes, gcp and kvm (seam, config, ID, Create, state-mapping table, IP source, Delete, ListByTag, classify table, Check, logging, tracing, tests, deployment, known gaps), shared gaps, and the proposed-features list. - **`docs/providers.md`**: the index. README "Adding a provider", CLAUDE.md and the architecture.md components row point at the new files. ## Two rules the old blueprint did not have Both found by reading the callers while verifying: - No caller puts a deadline on the context, and `Sweeper.sweep` loops providers sequentially, so one hung `ListByTag` stalls orphan GC for every provider. Now §1.5 and the `timeouts` axis. - The Stopped branch of `reconcileManaged` deletes and requeues without clearing `ProviderID`, so a backend that reports a freshly created, never started instance as stopped would have it deleted right after creation. Now a MUST in §2.2 and the `provisioning-state` axis (native, create-blocks, marker). ## Conventions - Code references are path plus symbol, never line numbers (the blueprint's `file:line` references had already drifted). - No em-dashes in the new files. ## Verification Recorded in `docs/plans-executions/2026-09-16-1108-provider-docs-split.md`: every relative link and anchor across the four new files plus README, CLAUDE.md and architecture.md resolves (script in the log); no em-dashes or line references in the new files; the contract contains none of kubernetes/gcp/kvm/libvirt/squid/google; every old §9 gap and proposal topic is present in the new files; every cited path and symbol exists; the 19 axis codes each appear once in the appendix table and in the template; `go build ./... && go test -short ./...` pass. Plans: `docs/plans/2026-09-16-0841-provider-blueprint.md` (blueprint) and `docs/plans/2026-09-16-1108-provider-docs-split.md` (split), with paired execution logs. 🤖 Generated with [Claude Code](https://claude.com/claude-code)
kacerr added 2 commits 2026-09-16 10:58:09 +02:00
docs/providers.md collects the provider contract that was spread across
comments, callers and per-provider docs: MUST/SHOULD/MAY rules per method,
each tied to the reconciler or GC behaviour it protects, the error taxonomy,
a feature matrix for kubernetes/gcp/kvm with file:line notes, a checklist for
adding a provider, and the known gaps. Linked from architecture.md and
CLAUDE.md.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
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>
kacerr added 1 commit 2026-09-16 11:14:07 +02:00
The blueprint reduced tracing to "don't open per-operation spans", which
reads as "nothing to do". Add an observability section: the operation
spans the decorators give for free, the child spans per backend call a
provider should add (parent-gated transport or a span decorator over the
SDK seam), the ctx/logger rules that keep traceID on log lines, and the
status per provider: kubernetes and gcp have child spans, kvm has none.
Matrix rows, the checklist item, gaps and a kvm proposal follow suit.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
kacerr added 1 commit 2026-09-16 11:18:42 +02:00
A pass over the API types, spec hash, health and discovery call sites,
manager manifests, samples, README, provider docs, plans and the PR review
found rules the blueprint did not state: the IP must be reachable on the
proxy port by the health engine and clients, providers must be safe for
concurrent use, the manager's read-only/128Mi runtime envelope, catalogue
edits bypass the spec hash, Delete is re-called while in progress, and
provider names must be DNS-1123. Adds matrix rows, a deployment checklist
item, and the still-open review findings and broken samples as gaps.

README's "Adding a provider" restated an outdated contract; it now points
to docs/providers.md, and the providers table gains the kvm row.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
kacerr added 7 commits 2026-09-16 13:47:26 +02:00
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Fully abstract: MUST/SHOULD/MAY rules with the caller behind each one,
19 behaviour-profile axes with stable codes, credential hygiene, testing
obligations, the checklist and the contract's known limits.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Twenty-four fill-in entries, one per decision the contract leaves to the
provider, numbered to match the contract's profile table.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Profile table keyed on the contract's axis codes, per-provider reference
sections for kubernetes, gcp and kvm, shared gaps and proposed features.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
kacerr changed title from Provider blueprint: contract rules, feature matrix and gaps (docs/providers.md) to Provider docs: generic contract, spec template and appendix on the existing providers 2026-09-16 13:48:11 +02:00
kacerr merged commit 0dc25a1637 into main 2026-09-16 13:48:40 +02:00
Sign in to join this conversation.
No Reviewers
No labels
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: kacerr/egress-proxies-operator#7