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>
66 lines
3.3 KiB
Markdown
66 lines
3.3 KiB
Markdown
# Execution: Split the provider blueprint into contract, appendix, template and index
|
|
|
|
Plan: [docs/plans/2026-09-16-1108-provider-docs-split.md](../plans/2026-09-16-1108-provider-docs-split.md)
|
|
|
|
- [x] Step 0 — Save and commit the plan
|
|
- [x] Step 1 — Write `docs/provider-contract.md`
|
|
- [ ] Step 2 — Write `docs/provider-spec-template.md`
|
|
- [ ] Step 3 — Write `docs/providers-existing.md`
|
|
- [ ] Step 4 — Rewrite `docs/providers.md` as the index; link edits
|
|
- [ ] Step 5 — Verification sweep
|
|
- [ ] Step 6 — Final summary, CHANGELOG after confirmation
|
|
|
|
## Step 0 — Save and commit the plan
|
|
|
|
Committed as `cf89ac4` on the existing `feat/provider-blueprint` branch, on
|
|
its own, before any document work. The pre-existing local modification of
|
|
`.claude/settings.json` was left out of the commit.
|
|
|
|
## Step 1 — Write `docs/provider-contract.md`
|
|
|
|
2026-09-16 11:17. Written from scratch rather than edited down from the old
|
|
blueprint, so that nothing provider-specific could survive by accident. Every
|
|
MUST names its caller by function (`reconcileManaged`, `replaceInstance`,
|
|
`reconcileDelete`, `providerFailure`, `deletionFailure`, `Sweeper.sweep`,
|
|
`Monitor.checkOnce`, `Monitor.run`, `registry.Build`) and states what breaks.
|
|
|
|
**Axis codes frozen** (19, §4.1 to §4.19): `readiness`, `create-return`,
|
|
`delete-return`, `ip-source`, `gc-mark`, `created-at`, `list-partial`,
|
|
`quota`, `not-found`, `primary-key`, `provisioning-state`, `async-ops`,
|
|
`secondary-resources`, `credentials`, `client-kind`, `timeouts`, `logging`,
|
|
`child-spans`, `backend-test`. The appendix table and the template are keyed
|
|
on these strings; the §4.20 summary table's last column gives the template
|
|
entry number each axis maps to.
|
|
|
|
**Two rules that were not in the old blueprint**, both found by reading the
|
|
callers while verifying:
|
|
|
|
- `Sweeper.sweep` loops providers sequentially in one goroutine, and no
|
|
caller puts a deadline on the context (only `Monitor.checkOnce` uses
|
|
`WithTimeout`). So a hung `ListByTag` stalls orphan GC for every provider.
|
|
Recorded in §1.5 and the `timeouts` axis.
|
|
- The Stopped branch of `reconcileManaged` calls `Delete` and requeues
|
|
without clearing `ProviderID`, then deletes again on every poll until
|
|
NotFound. A backend that reports a freshly created, never started instance
|
|
as stopped would have it deleted right after creation. Recorded as a MUST
|
|
in §2.2 and as the `provisioning-state` axis with three allowed profiles.
|
|
|
|
Checks run on the draft (all clean):
|
|
|
|
```sh
|
|
grep -niE "kubernetes|gcp|kvm|libvirt|squid|google|compute engine" docs/provider-contract.md
|
|
grep -n "—" docs/provider-contract.md
|
|
grep -nE '\.go:[0-9]+|:[0-9]+-[0-9]+' docs/provider-contract.md
|
|
grep -ohE "(internal|cmd|config|docs|api|hack|test)/[A-Za-z0-9_./-]+" docs/provider-contract.md | sort -u | while read p; do test -e "$p" || echo "MISSING $p"; done
|
|
```
|
|
|
|
The path check reports three expected misses: `config/samples/proxy_<type>.yaml`
|
|
is a pattern, `docs/provider-spec-template.md` is written in Step 2, and
|
|
`internal/provider/providertest` is a proposal named in §13.
|
|
|
|
Worth noting: the contract refers to "the operator pod" and "the cluster's
|
|
own API" rather than naming the platform, so that the abstractness grep stays
|
|
meaningful. The `hack/providers-dev.yaml` rule is phrased as "only if the type
|
|
needs no credentials" because that file exists for `make run-dev` without any
|
|
Secret.
|