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.
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)
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>
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>
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>
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>
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 providers2026-09-16 13:48:11 +02:00
kacerr
merged commit 0dc25a1637 into main2026-09-16 13:48:40 +02:00
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
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.mdis 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, theChecker, 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 todocs/<type>-provider-spec.mdand 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:
Sweeper.sweeploops providers sequentially, so one hungListByTagstalls orphan GC for every provider. Now §1.5 and thetimeoutsaxis.reconcileManageddeletes and requeues without clearingProviderID, 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 theprovisioning-stateaxis (native, create-blocks, marker).Conventions
file:linereferences had already drifted).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) anddocs/plans/2026-09-16-1108-provider-docs-split.md(split), with paired execution logs.🤖 Generated with Claude Code
Provider blueprint: contract rules, feature matrix and gaps (docs/providers.md)to Provider docs: generic contract, spec template and appendix on the existing providers